线性表基础
2.1 线性表的定义和基本操作
线性表是有序且有限的
2.1.2 存在一个唯一的被称为“第一个”的数据元素;
2.2.2 存在一个唯一的被称为“最后一个”的数据元素;
2.2.3 除了第一个元素外,每个元素均有唯一一个直接前驱;
2.2.4 除了最后一个元素外,每个元素均有唯一一个直接后继。
线性表(Linear List):是由n(n>=0)个数据元素(节点)a1,a2,…,an组成的有限序列
所有节点具有相同的数据类型
数据元素的个数n称为线性表的长度
当n=0时,称为空表
当n>0时,将非空的线性表记作:(a1,a2,…,an)
a1称为线性表的首节点,an称为尾节点
若线性表中的节点是按值(或按关键字值)由大到小(或由小到大)排列的,是有序的
线性表是一种相当灵活的数据结构,其长度可根据需要增长或缩短
对线性表的数据元素可以访问、插入和删除。
2.2 线性表的抽象数据结构定义
ListLength判断是否是空表的操作结果
L是空表返回0,否则返回其长度
·要将两个集合以线性表L表示,合并成一个新的线性表
A = AUB,扩大线性表LA,将B中存在而A中不存在的元素插入LA中
操作步骤:
- 从线性表LB中查看每个元素GetElem(LB,i)—>e
- 依值在线性表LA中进行访问,判断是否存在:LocElem(LA,e,equal())
- 若不存在,则插入 ListInsert(LA , n+1, e) 在最后位置插入
基本操作:
- 初始化LC为空表
- 分别从LA和 LB中取得当前元素ai和bj;
- 若ai<=bj,则将ai插入到LC中,否则将bj插入到LC中;
- 重复2和3步,直到LA或LB中的元素被取完;
- 将LA表或LB表剩余元素复制插入到LC表中。
算法实现:
void MergeList(List La , List Lb , List &.Lc)
{
InitList(Lc); //创建空表Lc
int i = j = 1 ; //链表已存在,0<=i<=ListLength(L)
int k = 0;
La_len = ListLength(La); //获取表的长度
Lb_len = ListLength(Lb);
while((i<=La_len)&&(j<=Lb_len)) //在合法的范围内操作
{
GetElem(La, i , ai); //获取链表的每个元素
GetElem(Lb, j , bj);
if(ai <= bj) //将两个表的同一个位置的 元素对比
ListInsert(Lc , ++k , ai); //在从0开始的位置开始先自增再插入
i++;
else
ListInsert(Lc , ++k , bj);
j++;
while( i<= la_len) //如果比较的元素的个数小于表的长度
{
GetElem(La , i++ , ai); //获取表的后面的元素
ListInsert(Lc , ++k , ai); //在Lc表后面一个个的插入
}
while( j<= lb_len)
{
GetElem(Lb , j++ , bj);
ListInsert(Lc , ++k , bj);
}
}
}
2.3 线性表的实现
2.3.1 顺序存储结构
顺序存储:把线性表的节点按逻辑顺序依次存放在一组地址连续的存储单元里。
(简称:顺序表)
·线性表的逻辑顺序与物理顺序一致;
·数据元素之间的关系是以元素在计算机内“物理位置相邻”来实现
线性表的第i个元素的存储位置是LOC(ai),第i+1个位置是LOC(ai+1) = LOC(ai)+l
即 LOC(ai+1) = LOC(a1)+(i-1)*l
2.3.2 存取结构:存取结构是在一个数据结构上对查找查找的时间性能的一种描述
随机存储结构:指在一个数据结构上进行查找的时间性能是O(n),即查找一个数据元素的时间复杂度是线性的,与该元素在结构中的位置有关
·单链表是一种顺序存取结构。
数组具有随机存储的特性,顺序表还应该有表示线性表长度的属性,所以用结构类型来定义顺序表类型。
- 静态结构:表一旦装满,不能扩充
/*静态顺序表的定义*/
#define MaxSize 50
typedef struct{
ElemType data[MaxSize]; //定义顺序表的元素
int length; //当前长度
}SqList; //顺序表的类型
- 动态结构:可以扩充,新的大小计入数据成员maxSize中
-
具体的各项增删改查的操作实现:#define InitSize 100 typedef struct{ ElemType *data; //指示动态分配数组的指针 int MaxSize, length; //数组的最大容量和当前长度 }SeqList; //动态分配数组顺序表类型
/*在顺序表的第i个位置插入元素*/ bool ListInsert(SqList &L, int i, ElemType e) { if(i<1||i>L.length+1) return false; if(L.length>=MaxSize) return false; for(int j=L.length;j>=i;j--) L.data[j]=L.data[j-1]; //位置后移 L.data[i-1]=e; //在后移的第一个位置前的位置赋值 L.length++; //长度+1 return true; } /*删除顺序表第i个位置的元素并将被删除的元素用引用变量e返回*/ bool ListDelete(SqList &L, int i , ElemType &e) { if(i<1||i>L.length) return false; e = L.data[i-1]; //第i个位赋值e for(int j = i;j<L.length;j++) //从插入的位置开始 { L.data[j-1] = L.data[j]; //后面所有的元素前移 } L.length--; return true; } /*查找线性表中值为e的元素并返回位置*/ int LocateElem(SqList L , ElemType e) { int i; for(i=0;i<L.length;i++) //依次遍历 { if(L.data[i]==e) //判断是否是e return i+1; //返回其位序 } return 0; } /**删除顺序表中最小值,由最后的元素填补这个位置**/ bool Del_Min(sqList &L , ElemType &value) { if(L.length == 0) return false; value = L.data[0]; int pos = 0; for(int i = 1; i<L.length; i++) if(L.data[i]<value) { value = L.data[i]; pos = i; } L.data[pos] = L.data[L.length - 1]; L.length--; return true; }