您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法学习总结-线性表的顺序存储与实现

2018-01-12 18:06 519 查看
  线性表的顺序存储是用一组地址连续的存储单元一次存储线性表的数据元素。

1.线性表的顺序存储

  假设线性表的每个数据元素需占用K个存储单元,并以元素所占的第一个存储单元的地址作为数据元素的存储地址。则线性表中序号为i的数据元素的存储地址LOC(ai)与序号为i+1的数据元素的存储地址LOC(ai+1)之间的关系为:

  LOC(ai+1)=LOC(ai)+K

  通常来说,线性表的i号元素的存储地址为:

  LOC(ai+1)=LOC(a0)+i×K

  其中LOC(a0)为0号元素的存储地址,通常称为线性表的起始地址。

  线性表的这种机内表示称作线性表的顺序存储。它的特点是,以数据元素在机内存储地址相邻来表示线性表中数据元素之间的逻辑关机。每一个数据元素的存储地址都和线性表的起始地址相差一个与数据据元素在线性表中的序号成正比的常数。由此,只要确定了线性表的起始地址,线性表中的任何一个数据元素都可以随机存取,因此线性表的顺序存储结构时一种随机的存储结构。如图所示:



线性表的顺序存储

  由于高级语言中的数组具有随机存储的特性,因此在抽象数据类型的实现中都是使用数组来描述数据结构的顺序存储结构。线性表中的数据元素在一次存放的数组中的时候,线性表中序号为i的数据元素对应的数组下标页为i,即数据元素在线性表中的序号与数据元素在数组中的下标相同。

  如果线性表中的数据元素是对象是,数组存放的是对象的引用,即线性表中所有数据元素的对象引用是存放在一组连续的地址空间中。



数组存储对象引用

2.线性表的操作

  由于线性表的长度可变,不同的问题所需的最大长度不同,那么在线性表的具体视线中我们是使用动态扩展数组大小的方式来完成线性表长度的不同要求的。

  在使用数组实现线性表的操作中,经常会遇到在数组中进行数据元素的查找、添加、删除等操作。

  查找:在数组中进行查找,最简单的方法就是顺序查找,平均时间复杂度θ(n).

  添加:在数组中添加数据元素,通常是在数组中下标为i(0≤i≤n)的位置添加数据元素,而将原来下标从i开始的数组中所有后续元素依次后移,如图所示:



在数组下标i处插入元素e

  代码:

for(int j = n;j > i;j--){
a[j] = a[j - 1];
}
a[i] = e;


  时间复杂度:θ(n)。

  删除:与添加相似。

3.线性表的数组实现

public class ListArray implements List{
//数组的默认大小
private final int LEN = 8;
//数据元素比较策略
private Strategy strategy;
//线性表中的数据元素的个数
private int size;
//数据元素数组
private Object[] elements;
//构造方法
public ListArray(){
this(new DefaultStrategy());
}
public ListArray(Strategy strategy){
this.strategy = strategy;
size = 0;
elements = new Object[LEN];
}
//返回线性表的大小,即数据元素的个数。
public int getSize(){
return size;
}
//如果线性表为空返回true,否则返回false。
public boolean isEmpty(){
return size = 0;
}
//判断线性表是否包含数据元素e
public boolean contaions(Object e){
for(int i = 0;i < size;i++){
if(strategy.equal(e,elements[i])){
return true;
}
return false;
}
}
//返回数据元素e在线性表中的序号
public int indexOf(Object e){
for(int i = 0;i < size;i++){
if(strategy.equal(e,elements[i])){
return i;
}
return -1;
}
}
//将数据元素e插入到线性表中i号位置
public void insert(int i,Object e)throws OutOfBoundaryException{
if(i < 0||i > size){
throw new OutOfBoundaryException(“错误,指定的插入序号越界。”)
}
if(size ≥ elements.length){
expandSpace();
}
for(int j = size;j > i;j--){
elements[j] = elements[j-1];
}
elements[i] = e;
size++;
return;
}
public void expandSpace(){
Object[] a = new Object[elements.length*2];
for(int i = 0;i < elements.length;i++){
a[i] = elements[i];
}
elements = a;
}
//将数据元素e插入到元素obj之前
public boolean insertBefore(Object obj,Object e){
int i = indexOf(obj);
if(i < 0){
insert(i,e);
return false;
}
return true;
}
//将数据元素e插入到元素obj之后
<
b30e
span class="hljs-keyword">public boolean insertAfter(Object obj,Object e){
int i = indexOf(obj);
if(i < 0){
insert(i+1,e);
return false;
}
return true;
}
//删除线性表中序号为i的元素,并返回之
public Object remove(int i) throws OutOfBoundaryException{
if(i < 0||i > size){
throw new OutOfBoundaryException(“错误,指定的删除序号越界。”)
}
Object obj = elements[i];
for(int j = i;j < size-1;j++){
elements[j] = elements[j + 1];
}
elements[--size] = null;
return obj;
}
//删除线性表中第一个与e相同的元素
public boolean remove(Object e){
int i = indexOf(e);
if(i < 0){
remove(i)
return false;
}
return true;
}
//替换线性表中序号为i的数据元素为e,返回原数据元素
public Object replace(int i,Object e)throws OutOfBoundaryException{
if(i < 0||i > size){
throw new OutOfBoundaryException(“错误,指定的序号越界。”)
}
Object obj = elements[i];
elements[i] = e;
return obj;
}
//返回线性表中序号为i的数据元素
public Object get(int i)throws OutOfBoundaryException{
if(i < 0||i > size){
throw new OutOfBoundaryException(“错误,指定的序号越界。”)
}
return elements[i];
}
}


  说明:在ArrayList类中共有4个成员变量。其中elements数组以及size用于存储线性表中的数据元素以及表明线性表中数据元素的个数;而strategy是用来完成线性表中数据元素的比较策略;LEN是elements数组的初始默认大小,数组的大小在后续的插入操作中可能会发生变化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 java