《大话数据结构》--线性表顺序存储

268 阅读3分钟

线性表介绍

  • 线性表:0个或多个数据元素的有限序列。若将线性表记为(a1,·······,ai-1,ai,ai+1,·······an),则ai-1是ai的直接前驱元素,ai+1是ai的直接后驱元素。
  • 线性表元素的个数n(n>0)定义为线性表的长度,当n=0时,称为空表。

顺序存储介绍

定义

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

实现

一维数组实现

数组长度和线性表长度的区别

数组长度是存放线性表的存储空间的长度,存储分配后长度一般不变。

线性表长度是线性表中数据元素的个数,随着插入删除操作,长度会发生变化。

地址计算方法

存储器中的每个存储单元都有自己的编号,这个编号称之为地址。

假设占用的是c个存储单元,线性表中第i+1个存储元素的存储位置和第i个存储元素的存储位置满足以下关系(LOC表示获得存储位置的函数)

LOC(ai+1) = LOC(ai) + c   或    LOC(ai) = LOC(a1) + (i-1)c

常量定义

  • private static final Integer MAXSIZE = 20;  // 数组长度

  • private static Integer[] data; // 存储元素的数组

  • private static Integer length = 0; // 线性表的长度

操作-获取

获取元素就是将线性表data中第i个位置的元素值返回。

思路

只要i的数值在数组下标范围内,就把数组第i-1下标的值返回即可。

代码

static Integer getElem(int i) throws Exception {    
    if(data.length == 0 || i < 1 || i > length) {        
        throw new Exception("data为空或i范围错误");    
    }    
    return data[i-1];
}

操作-插入

在线性表的第i个位置插入新元素elementData

思路

  1. 如果插入位置不合理,抛出异常;

  2. 如果线性表长度大于等于数组长度,则抛出异常或动态增加容量,

  3. 从最后一个元素开始向前遍历到第;个位置,分别将它们都向后移动一个位置

  4. 将要插入元素填入位置i处;

  5. 表长加1。

图示

代码

static void listInsert(Integer i, Integer elementData) throws Exception {    
    if (length > MAXSIZE) { throw new Exception("顺序线性表已经满");    }    
    if (i > length + 1 || i < 1) {  throw new Exception("i不在范围内");    }    
    if (i <= length) {        
        for (int k = length - 1; k >= i - 1; k--) {            
            data[k + 1] = data[k];        
        }    
    }    
    data[i-1] = elementData;    
    length ++;
}

操作-删除

删除线性表的第i个位置的元素并返回

思路

  1. 如果删除位置不合理,抛出异常
  2. 取出删除元素
  3. 从删除元素位置开始遍历到最后一个元素位置,分别将他们都向前移动一个位置
  4. 表长减1

图示

代码

static Integer listDelete(Integer i) throws Exception {    
    Integer result = null;    
    if (length == 0) {   throw new Exception("顺序线性表是空的");    }    
    if (i > length || i < 1) {   throw new Exception("删除位置不正确");    }    
    result = data[i-1];    
    if (i < length) {        
        for (int k = i-1; k < length - 1; k++) {           
            data[k] = data[k+1];        
        }    
    }    
    length --;    
    return result;
}

测试

public static void main(String[] args) throws Exception {    
    data = new Integer[MAXSIZE];    
    for (int i=0; i<10; i++) {        
        data[i] = i;        
        length ++;    
    }    
    System.out.println("获取元素"); 
    System.out.println(getElem(3));    
    System.out.println("插入前");    
    printList();    
    listInsert(3, 13);    
    System.out.println("插入后");    
    printList();    
    System.out.println("删除元素:" + listDelete(5));    
    System.out.println("删除后");    
    printList();
}

优缺点

优点

  • 无需为表中元素的逻辑关系而增加额外的存储空间。
  • 可以快速的存取表中任意位置的元素。

缺点

  • 插入和删除操作需要移动大量元素
  • 当线性表长度变化较大时,难以确定存储空间的容量
  • 造成存储空间的‘碎片‘