1.顺序存储结构
用一组连续的内存单元依次存放线性表的数据元素,元素在内存的物理存储次序与他们在线性表中的逻辑次序相同。
线性表的数据元素属于同一数据类型,设每个元素占用c字节,a(0)的存储地址为Loc(a(0)),则a(i)的存储地址Loc(a(i))为
Loc(a(i)) = Loc(a(0)) + i * c
可见,顺序表元素a(0)的存储地址是它在线性表中位置i的线性函数,与线性表的长度n没有关系;而计算一个元素地址所需的时间是一个常量,与元素位置i无关。因此,存取任何一个元素的时间复杂度都是O(1)。即,顺序表是一种随机存储结构。
顺序表通常采用数组来存储数据元素,数组一旦占用一片存储空间,地址和长度就是确定的,不能更改,因此,数组只能进行赋值和取值两种操作,不能进行插入和删除,这也就决定了顺序表的插入和删除只能间接进行,即移动数据元素。
2.顺序表类的java实现
3.效率分析package linearList; public class SeqList<E> implements LList<E>{ private Object[] table;//对象数组 private int n;//顺序表长度 /* * 构造方法,创建指定容量的空表 */ public SeqList(int capacity){ this.table = new Object[Math.abs(capacity)];//Math.abs(i)返回i的绝对值 this.n = 0; } /* * 构造方法,指定空表的默认容量 */ public SeqList(){ this(16); } /* * 判断是否为空,若为空,返回true */ public boolean isEmpty(){ return this.n == 0; } /* * 返回线性表长度 */ public int length(){ return this.n; } /* * 返回序号为index的对象 */ public E get(int index){ if(index>=0&&index<this.n){ return (E)this.table[index]; }else{ return null; } } /* * 设置序号为index的对象的值为element,返回原对象 */ public E set(int index,E element){ if(index>=0&&index<this.n&&element!=null){ E old = (E)this.table[index]; this.table[index] = element; return old; }else{ return null; } } /* * 插入element对象,插入位置序号为index */ public boolean add(int index,E element){ //不能插入null if(element==null){ return false; } //数组扩容 if(this.n==table.length){ Object[] temp = this.table; this.table = new Object[temp.length*2]; for(int i=0;i<temp.length;i++){ this.table[i] = temp[i]; } } //下标容错,增强程序的健壮性 if(index<0){ index = 0; } if(index>this.n){ index = this.n; } //插入元素,元素后移 for(int i=this.n-1;i>=index;i--){ table[i+1] = table[i]; } table[index] = element; this.n++; return true; } /* * 插入element对象,位置没有约定,即在顺序表最后插入 */ public boolean add(E element){ this.add(this.n, element); return true; } /* * 移除序号为index的对象,返回被移除的对象 */ public E remove(int index){ if(this.n!=0&&index>=0&&index<this.n){ E old = (E)table[index]; for(int i=index;i<this.n-1;i++){ this.table[i] = this.table[i+1]; } this.table[this.n-1] = null; this.n--; return old; } return null; } /* * 清空线性表 */ public void clear(){ if(this.n!=0){ for(int i=0;i<this.n;i++){ this.table[i] = null; } this.n = 0; } } /* * 返回所有元素值 */ public String toString(){ String str = "("; if(this.n!=0){ for(int i=0;i<this.n-1;i++){ str += this.table[i].toString()+","; } str += this.table[this.n-1].toString(); } return str+")"; } //方法调用,即操作顺序表(增删改查) public static void main(String[] args) { } }
由于顺序表是一种随即结构,存取任何一个元素的get(),set()方法的时间复杂度都是O(1)
对顺序表的增加和删除操作时,主要的时间消耗是移动元素时发生的,设表长度为n,在第i个位置插入元素的概率是p(i),则插入一个元素的平均移动次数为
(n-1)* p(i)的连加和
如果在各个位置插入元素的概率相同,即p(0)=p(1)=.......=p(n)=1/(n+1),则时间复杂度为O(n),删除一个元素也是O(n).
综上所述,我们发现顺序表有两个特点,第一:元素的物理存储顺序直接反映了元素的逻辑顺序,可以随机存取元素;第二:插入和删除的操作效率很低。因此我们在需要频繁查询的场合适于用顺序存储结构,但是当需要频繁的添加和删除操作时就不能用顺序存储结构了,我们需要另寻他法。
线性表之顺序表
最新推荐文章于 2018-04-06 17:05:27 发布