本文数据结构讲解参考书目:
通过网盘分享的文件:数据结构 C语言版.pdf
链接: https://pan.baidu.com/s/159y_QTbXqpMhNCNP_Fls9g?pwd=ze8e 提取码: ze8e
目录
前言
一.线性表的定义
二.线性表的基本操作
三.线性表的顺序存储和表示
四.顺序表中基本操作的实现
1.顺序表的初始化
【算法步骤】
【算法描述】
2.顺序表的取值
【算法步骤】
3.顺序表的查找
【算法步骤】
【算法描述】
4.顺序表的插入
[算法步骤】
【算法描述】
5.顺序表的删除
[算法步骤】
【算法描述】
前言
线性表是最常用且最简单的一种数据结构。简单的讲一个线性表就是n个数据元素的有限序列。(A,B,C......Z)其中这就表示是一个线性表,A称为元素,它可以是一个数或一种符号,甚至是更复杂的信息。
如果在稍微复杂的线性表中,一个数据元素可以由若干个数据项组成,在这种情况下,把数据元素称作为记录,含有大量记录的线性表称为文件。
注:线性表中的数据元素可以是各种各样的,但同一线性表中的元素必定有相同特性,即属于同一数据对象,相邻数据元素之间存在的序偶关系。
将线性表记作:
线性表中的元素的个数n(n>=0)定义为线性表的长度,n=0时称为空表。
一.线性表的定义
ADT List
{
数据对象
数据关系
基本操作
}
二.线性表的基本操作
基本操作 | 初始条件 | 操作结果 |
InitList(&L) | \ | 构造一个空的线性表L |
DestroyList(&L) | 线性表L已存在 | 销毁线性表L |
ClearList (&L) | 线性表L已存在 | 将L重置为空表 |
ListEmpty(L) | 线性表L已存在 | 若L为空表, 则返回true, 否则返回false |
ListLength(L) | 线性表L已存在 | 返回L中数据元素个数 |
GetElem(L,i,&e) | 线性表L巳存在,且1<=i<=ListLength(L) | 用e返回L中第1个数据元素的值 |
LocateElem(L,e) | 线性表L已存在 | 返回L中第1个 值与e相同的元素在 L中的位置 。若这样的数据元素不存在 , 则返回值为0 |
PriorElem(r,,cur_e,&pre_e) | 线性表L已存在 | 若cur_e是L的数据元素,且不是第一个,则用pre_e返回其前驱,否则操作失败,pre_e无定义 |
NextElem(L,cur_e,&next_e) | 线性表L已存在 | 若cur_e是L的数据元素,且不是最后一个,则用next_e返回其后继,否则操作失败,next_e无定义 |
ListInsert(&L,i,e) | 线性表L巳存在,且1<=i<=ListLength(L)+1 | 在 L中第1个位置之前插入新的数据元素 e, L的长度加1 |
ListDelete(&L,i) | 线性表L已存在且非空 ,且1<=i<=ListLength(L) | 删除L的第1个数据元素,L的长度减1 |
TraverseList(L) | 线性表L巳存在 | 对线性表L进行遍历,在遍历过程中对 L的每个结点访问一次 |
三.线性表的顺序存储和表示
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素, 这种表示 也称作线性表的顺序存储结构或顺序映像。
通常, 称这种存储结构的线性表为顺序表(Sequential List)。其特点是,逻辑上相邻的数据元素, 其物理次序也是相邻的。
则线性表中第i+ 1个数据元素的存储位置LOC(a+1)和第i个数据元素的存 储位置LOC(a;)之间满足下列关系:
LOC(a+ 1) = LOC(a) + I(l表示每个元素占用的存储单元)
一般来说, 线性表的第l个数据元素ai的存储位置为:
LOC(ai) = LOC(a1) + (i - 1) x l
四.顺序表中基本操作的实现
1.顺序表的初始化
【算法步骤】
1.为顺序表L动态分配一个预定义大小的数组空间,使elem指向这段空间的基地址。
2.将表的当前长度设为0。
【算法描述】
Status InitList(SqList &L)
{//构造一个空的顺序表 L
L.elem= new ElemType[MAXSIZE]; / /为顺序表分配一个大小为MAXSIZE的数组空间
if (! L. elem) exit (OVERFLOW); //存储分配失败退出
L.length=0; //空表长度为0
return OK;
}
动态分配线性表的存储区域可以更有效地利用系统的资源 , 当不需要该线性表时 , 可以使用 销毁操作及时释放占用的存储空间。
2.顺序表的取值
取值操作是根据指定的位置序号i, 获取顺序表中第i个数据元素的值。 由千顺序存储结构具有随机存取的特点 , 可以直接通过数组下标定位得到,elem[ i-1]单元存 储第i个数据元素。
【算法步骤】
1.判断指定的位置序号 i 值是否合理 (<=i<=L.length), 若不合理,则返回ERROR。
2.若 i 值合理,则将第 i 个数据元素 L.elem[i-1]赋给参数 e, 通过 e返回第 i个数据元素的 传值。
【算法描述】
Status GetElem(SqList L,int i,ElemType &e)
{
if {i<ll li>L.length) return ERROR; //判断l. 值是否合理,若不合理, 返回 ERROR
e=L.elem[i一 1]; //elem[i-1] 单元存储第 i 个数据元素
return OK;
}
顺序表取值算法的时间复杂度为O(1)
3.顺序表的查找
【算法步骤】
1.从第一个元素起,依次和 e相比较,若找到与 e相等的元素 L.elem[i], 则查找成功,返回 该元素的序号 i+1。
2.若查遍整个顺序表都没有找到,则查找失败, 返回0。
【算法描述】
int LocateELem(SqList L,ElemType e)
{//在顺序表1中查找值为e的数据元素, 返回其序号
for(i=O;i< L.length;i++)
if(L.elem[i)==e) return i+l; //查找成功, 返回序号 i+l
return O; //查找失败, 返回 0
}
当在顺序表中查找一个数据元素时,其时间主要耗费在数据的比较上, 而比较的次数取决千 被查元素在线性表中的位置。
在查找时,为确定元素在顺序表中的位置, 需和给定值进行比较的数据元素个数的期望值称 为查找算法在查找成功时的平均查找长度 (Average Search L ength, ASL)。
顺序表按值查找算法的平均时间复杂度为 O(n)。
4.顺序表的插入
[算法步骤】
1.判断插入位置l是否合法(i 值的合法范围是1<=i<=n+ I), 若不合法 则返回 ERROR。
2.判断顺序表的存储空间是否已满,若满见肤返回 ERROR。
3.将第n个至第l个位置的元素依次向后移动一个位置,空出第l个位置(i =n+1时无需 移动)。
4.将要插入的新元素e放入第i个位置.
5.表长加1。
【算法描述】
Status Listinsert(SqList &L,int i ,ElemType e)
{//在顺序表 L 中第 l. 个位置之前插入新的元素 e, i值的合法范围是 1<=i<=L.length+l
if((i<l) || (i>L.length+l)) return ERROR; //i值不合法
if(L.length==MAXSIZE) return ERROR; //当前存储空间已满
for (j=L. length-1; j>=i-1; j--)
L.elem[j+l]=L.elem[j]; // 插入位置及之后的元素后移
L.elem[i-l)=e; //将新元素e放入第l个位置
++L.length; //表长加1
return OK;
}
顺序表插入算法的平均时间复杂度为 O(n)
5.顺序表的删除
一般情况下,删除第i(1<=i<=n) 个元素时需将第i+ 1 个至第n 个元素(共 n-i 个元素) 依次向前移动一个位置 (i = n 时无需移动)。
[算法步骤】
1.判断删除位置 i是否合法(合法值为1<=i<=n), 若不合法则返回 ERROR。
2.将第i+1个至第n个的元素依次向前移动一个位置 (i = n时无需移动)。
3.表长减 1。
【算法描述】
Status ListDelete(SqList &L,int i)
{//在顺序表L中删除第J.个元素,J.值的合法范围是 1<=i<=L. length
if((i<l) || (i>L.length)) return ERROR; //i值不合法
for (j=i; j <=L. length-1; j ++)
L.elem[j-1)=1.elem[j); //被删除元素之后的元素前移
--L.length; //表长减1
return OK;
}
顺序表删除算法的平均时间复杂度为O(n)
顺序表可以随机存取表中任一元素,其存储位置可用一个简单、直观的公式来表示。然而, 从另一方面来看,这个特点也造成了这种存储结构的缺点:在做插入或删除操作时,需移动大 最元素。 另外由千数组有长度相对固定的静态特性, 当表中数据元素个数较多且变化较大时, 操作过程相对复杂,必然导致存储空间的浪费。 所有这些问题,都可以通过线性表的另一种表 示方法�式存储结构来解决。