线性表的基本运算包括如下内容:
(1)初始化
初始化表(InitList)即构造一个空的线性表L。
初始化顺序表设置其结点数量ListLen为0,后面需要添加的数据元素将从顺序表的第一个位置存储。
示例:
void SLList(SLType){ //初始化顺序表
SL.listLen = 0; //初始化为空表
}
(2)计算表长
计算表长(ListLength)即计算线性表L中结点的个数。
由于在示例A中,类SLType使用ListLen来表示顺序表的结点数量,因此只要返回值即可。
示例:
int SLLength(SLType SL){
return (SL.ListLen); //返回顺序表的元素数量(结点数量)
}
(3)获取结点
获取结点(GetNode)即获取线性表L中第i个结点的数据,这里1《i《ListLength(L)。
(4)查找结点
查找结点(LocateNode)即在线性表L中查找值为x的结点,并返回该结点在线性表L中的位置。如果在线性表中没有找到值为x的结点,则返回一个错误标志。
查找结点两种方式:
1.按序号查找结点;
2.按关键字查找结点。
a)按序号查找结点
对于顺序表,其存储本身就是一个数组,序号就是数据元素在数组中的位置,即数组的下标标号。
示例:
DATA SLFindByNum(SLType SL,int n){ //根据序号返回数据元素
if(n<1 || n>SL.ListLen+1){ //元素序号不正确,
System.out.println("结点序号错误,不能返回结点!\n");
return null; //不成功,则返回0
}
return SL.ListData[n];
}
b)按序号查找结点示例:
DATA SLFindByCont(SLType SL,String key){ //按关键字查询结点
int i;
for(i=1;i<=SL.ListLen;i++){
if(SL.ListData[i].key.compareTo(key)==0){ //如果找到所需结点
return i; //返回结点序号
}
}
return 0; //搜索整个表后仍没有找到,则返回0
}
【注】线性表中可能含有多个与x值相同的结点,则此时就返回第一次查找的结点。
(5)插入节点
插入节点(InsertList)即在线性表L的第i个位置插入一个新的节点,使得其后 的结点均编号依次加1。这时,插入一个新的结点后,线性表L的长度将变为n+1。
插入节点操作的难度在于随后的每个结点数据都要进行移动,计算了较大。
示例:
int SLInsert(SLType SL,int n,DATA data){
int i;
if(SL.ListLen >= MAXLEN){ //顺序表结点数量已超过最大数量
System.out.println("顺序表已满,不能插入结点!\n");
return 0; //返回0表示插入不成功
}
if(n<1 || n>SL.ListLen-1){
System.out.println("顺序表已满,不能插入结点!\n");
return 0; //返回0表示插入不成功
}
for(i=SL.ListLen; i>=n; i--){ //将顺序表中的数据后移动
SL.ListData[i+1] = SL.ListData[i]
}
SL.ListData[n] = data; //插入结点
SL.ListLen++; //顺序表结点数量增加1,即更新顺序表长度
return 1; //成功插入,返回1
}
【注】判断顺序表结点数量是否已超过最大数量,以及插入结点是否正确,满足条件后,将顺序表中数据向后移动,同时插入结点,并更新结点数量ListLen,即顺序表的长度。
【追加结点】可看做插入结点的一种特殊形式,相当于在顺序表末尾新增一个数据结点。
实例:
int SLAdd(SLType SL, DATA data){ //增加元素到顺序表尾部
if(SL.ListLen >= MAXLEN){ //顺序表已满
System.out.println("顺序表已满,不能再添加结点了!\n");
return 0;
}
SL.ListData[++SL.ListLen] = data;
return 1;
}
仅判断顺序表是否已满,然后追加结点,并更新顺序表结点数量ListLen,即顺序表的长度。
(6)删除节点
删除节点(DeleteList)即删除线性表L中第i个结点,使得其后的所有结点编号依次减1.此时,线性表L的长度将变为n-1。
实例:
int SLDelete(SLType SL,int n){ //删除顺序表中的数据元素
int i;
if(n<1 || n>SL.ListLen+1){ //删除结点序号不正确
System.out.println("删除结点序号错误,不能删除结点!\n");
return 0; //删除不成功,返回0
}
for(i=SL.ListLen; i>=n; i--){ //将顺序表中的数据向前移动
SL.ListData[i] = SL.ListData[i+1]
}
SL.ListLen--; //顺序表结点数量减1,即更新顺序表长度
return 1; //成功删除,返回1
}
判断删除的结点序号是否正确,然后开始移动数据,并更新结点数量ListLen,即更新删除数据表的长度。
(8)显示所有结点
显示所有结点数据并不是一个数据结构基本的运算,因为其可以简单地逐个引用结点来实现。
int SLALL(SLType SL){//显示顺序表中的所有结点
int i;
for(i=1;i<=SL.ListLen;i++){
System.out.println();
}
return 0;
}
线性表的两种保存方式:
1.顺序存储结构(顺序表);
2.链式存储结构(链表)。
A.顺序表结构
顺序表(SequentialList),依次存放,因此只要知道该顺序表的首地址及每个数据元素所占用的存储长度,即可计算出任何一个数据元素(即数据结点)的位置。
示例A:
static final int MAXLEN = 100;//定义顺序表的最大长度
class DATA{
String key; //结点的关键字
String name;
int age;
} //定义结点
class SLType{ //定义顺序表结构
DATA[ ] ListData = new DATA[MAXLEN + 1]; //保存顺序表的结构数组
int ListLen; //顺序表已存结点的数量,即当前顺序表的长度
}
示例:顺序表操作实例