如果一个数据元素序列满足:
- 除第一个和最后一个数据元素外,每个数据元素都只有一个前驱数据元素和一个后继数据元素;
- 第一个数据元素没有前驱数据元素;
- 最后一个数据元素没有后继数据元素;
则称这样的数据结构为线性结构。线性表、堆栈、队列、串和数组都属于线性结构。
线性表是一种可以在任意位置进行插入和删除数据元素操作的、由n(n>=0)个相同类型数据元素a0,a1,a2,a3…..an-1组成的线性结构。
顺序表的主要特点是:
- 在顺序表插入和删除一个数据元素成员的时间复杂度为O(n)。
- 顺序表支持随机读取,因此,顺序表读取数据元素的时间复杂度为O(1)。
- 顺序表的主要优点是:支持随机读取,以及内存空间利用效率高。
- 顺序表的主要缺点是:需要预先给出数组的最大数据元素个数,但数组的最大元素个数很难准确给出。另外,插入和删除操作时需要移动较多的数据元素。
首先设计一个线性表接口List,线性表接口List给出了任何实现线性表功能的类中必须要实现的成员函数原型,这有两方面的作用:一方面,设计基础软件模块(如顺序表类和单链表类等)的设计者,可以根据接口List规范的成员函数(包括成员函数的访问权限,成员函数名,成员函数的返回类型,每个参数的参数类型)来实现成员函数,这样,凡是实现接口List的类,无论是顺序表类还是单链表类,只是实现操作的具体方法不同,所实现的功能和调用的形式都相同;另一方面,使用基础软件模块(如顺序表类和单链表类等)的使用者在定义了对象后,可以根据接口List规范的成员函数原型来调用成员函数。因此可以说,线性表接口List定义了实现该接口类的外部公共接口。
public interface List {
//线性表接口List给出了任何实现线性表功能的类中必须要实现的成员函数原型
public void insert(int i,Object obj)throws Exception; //插入
public Object delete(int i)throws Exception; //删除
public Object getData(int i)throws Exception; //取数据元素
public int size(); //求数据元素个数
public boolean isEmpty(); //判断是否空
}
实现顺序存储结构的方法是使用数组。数组将顺序表的数据元素存储在一块连续地址的内存单元中。线性表的存储结构示意图如下图所示,其中a0,a1,a2,a3等表示顺序表中存储的数据元素,listArray表示存储数据元素的数组,maxSize表示数组的最大允许数据元素个数,size表示数组的当前数据元素个数。
顺序表类的设计如下:
public class SeqList implements List{
final int defaultSize=10;
int maxSize; //表示数组允许存储的数据元素
int size; //数组的当前数据元素个数
Object[] listArray; //表示存储数据元素的数组
public SeqList(){ //无参构造方法重载
initiate(defaultSize);
}
public SeqList(int size){ //有参构造方法重载
initiate(size);
}
private void initiate(int sz){ //初始化
maxSize=sz;
size=0;
listArray=new Object[sz];
}
public void insert(int i,Object obj)throws Exception{ //接口中的insert方法实现
if(size==maxSize){
throw new Exception("顺序表已满,无法插入!");
}
if(i<0||i>size){
throw new Exception("参数错误!");
}
for(int j=size;j>i;j--){
listArray[j]=listArray[j-1]; //将listArray[i]到listArray[size-1]之间的数组元素向后平移一位
}
listArray[i]=obj; //在listArray[i]处插入Object类型的实例obj(有可能是数字,字符,或者其他对象,因此用Object类型)
size++; //数组长度加一
}
public Object delete(int i)throws Exception{
if(size==0){
throw new Exception("顺序表已空,无法删除!");
}
if(i<0||i>size-1){
throw new Exception("参数错误!");
}
Object it = listArray[i]; //定义it存储将要被删除的数据元素
for(int j=i;j<size-1;j++){
listArray[j]=listArray[j+1];
}
size--; //size--的语义包括删除listArray[size-1],即线性表的最后一个元素
return it;
}
public Object getData(int i)throws Exception{
if(i<0||i>=size){
throw new Exception("参数错误!");
}
return listArray[i];
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public int MoreDataDelete(SeqList L,Object x)throws Exception{
int i,j;
int tag=0;
for(i=0;i<L.size;i++){
if(x.equals(L.getData(i))){
L.delete(i);
i--;
tag=1;
}
}
return tag;
}
}