第2章--线性表
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1
可定义结构体数组
2
例 typedef struct card
{ int num;
char name[20];
n
char author[10];
char publisher[30];
备 float price;
用 }DATATYPE;
空 间
DATATYPE
library[M];
通信工程学院
顺序表的基本运算
从} ai+1开始向后逐个元素向前移动
a1 a2 ai-1 ai ai+1… an
for( j = i; j < list.n; j++){
list.a[ j ] = list.a[ j+1 ];
}20.09.2019
通信工程学院
删除运算
void delete( list, i , y ){
1.从ai+1节点开始向后,逐个向前搬动节点, 挤掉第i个元素
四.查找(算法2.4) 线性表的查找是指找出数据元素x在表
中的位序号,若v[i]==x,则算法返回值为i+1, 若不存在数据元素x则返回0
20.09.2019
通信工程学院
顺序存储的线性表
数组顺序存储结构的特点
任意元素获取容易实现,定位简单
存取时间短,存取时间与元素位置无关
元素更动(比如:插入和删除)时的搬移性
20.09.2019
通信工程学院
顺序存储的线性表
线性表的顺序分配是指:用一组连续编号的存 储单元依次存放各个数据元素。 根据一个数据元素占据m个存储单元,有:
LOC(ai)=LOC(a1)+(i-1)×m 用一维数组来实现线性表顺序存储结构
数组元素: a[0]、a[1]、a[2]、a[3]
线性表元素:a1、a2、 a3、 a4....
a1
a2
ai-1
anew
nodie
ai+1
…
an
for( j = list.n; j >= i; j--){
list.a[ j+1 ] = list.a[ j ];
}
20.09.2019
通信工程学院
插入运算
void insert( table, new_node, location){
搬动节点,腾空位置 在腾空的位置处,放入新的元素
通信工程学院
删除运算
三、删除运算(将第i个数据元素删去)
a1 a2 ai-1 ai ai+1 … an
a1 a2 ai-1 ai ai+1 … an
20.09.2019
通信工程学院
aai+n1 a…n an
从an开始向前逐个元素向前移动
for( j = list.n; j > i; j- -){ list.a[ j ] = list.a[ j+1 ];
(2)有且仅有一个结束节点(该节点只有一个 前趋节点,没有后继节点)
(3)其余节点有且仅有一个前趋和一个后继节点
k1 k2 k3 k4
k2 k1
k3
20.09.2019
通信工程学院
线性表常用的的运算
⑴初始化线性表 ⑵判表是否为空 ⑶求线性表的长度 ⑷读取线性表中第i个元素 ⑸查找满足给定条件的数据元素 ⑹在线性表的第i个位置之前插入一个 新的数据元素
a1 a2 ai-1 ai ai+1 …… an
a1
a2
ai-1
a a new
nodi e
i+1 ……
an
20.09.2019
通信工程学院
插入运算
a1 a2 ai-1 ai aai+i1 a.....i. ani
从ai开始,到an开始向后逐个移动
for( j = i; j < =list.n ; j++){ list.a[ j+1 ] = list.a[ j ]; }从an开始,向前的每个元素向后移一格
通信工程学院
出错处理
void error(int number){
switch(number){
case 1:
printf(“the list is full”);
break;
case 2:
printf(“can’t insert at i”);
break;
default:
printf(“unknown error”);
头插法建立单链表算法
算法思路
1)首先建立一个头结点,并使头结点的指针域
为空;
2)读入值ch;
3)建立一个新结点p;
4)将ch赋给p的数据域;
5)改变指针p的值,使p成为h的直接后继;
if (i<1 || i > list.n ) error(2);
else{
for(j = list.n-1 ; j >= i-1 ; j--){ list.a[ j+1 ] = list.a[ j ];
}
list.a[ i-1 ] = x;
}
} } 20.09.2019
list.n = list.n +1;
从链点的生成过程中体会动态内存申请的动作. 第一种方法:(头插法) 每次输入的元素插入到链表头,实质是从表的最后一 个元素开始,从后往前的生成结点来建立链表。
第二种方法:(尾插法)
每次输入的元素插入到链表尾,实质是从第一个元素 开始,从前往后的生成新结点来建立链表的。
20.09.2019
通信工程学院
第二章 线性表
[内容提要]
1、线性表的定义、逻辑结构及基本运算 2、线性表的顺序存储结构及基本运算 3、线性表的链式存储结构及基本运算 4、数组的定义及其存储方式 5、线性表的应用示例
20.09.2019
通信工程学院
线性表:由n(n≥0)个a1,a2,…an组成的有
限序列。其逻辑结构是线性结构。
(1)有且仅有一个开始节点(该节点只有一个 后继节点,没有前趋节点)
}
}
20.09.2019
通信工程学院
插入算法的算法效率
假设在第i个元素之前插入一个元素的概率 为Pi,所需移动数据元素的平均次数为:
n1
EiPi (ni 1)
i1
若认为 Pi
1 n 1
则Ei
1
n 1
(n i 1)
n
n 1 i1
2
T n On
20.09.2019
20.09.2019
通信工程学院
void delete( list, i , y ){
if( list .n < 1) error(3);
else{ if( i < 0 || i > list .n ) error(4); else{ for(j = i ; j < list . n ; j++){ list . a[ j ] = list . a[ j+1 ]; }
2、数组长度因为减少了一个新元素而减一
}
补充算法:a.删除了空表
20.09.2019
b.删除位置i不正确
通信工程学院
顺序表的删除算法
算法思路: (1)判断顺序表是否为空 (2)判断i值是否超出所允许的范围
(1≤i≤n),若是,则进行“超出范围” 处理; (3)把第i个元素赋给y ;把第i个元素后的所 有元素依次向前移动一个位置; (4)线性表长度减1。
20.09.2019
通信工程学院
顺序表的类型定义
#define Maxsize maxlen
/*maxlen表示线性表可能的最大数据元素数目*/
typedef int elemtype;
/*elemtype表示数据元素类型,此处定义为int*/
typedef struct
{elemtype v[Maxsize];
}}
}
20.09.2019
list . n = list . n -1;
通信工程学院
出错处理
void error(int number){ switch(number){ case 3: printf(“the list is empty”); break; default: printf(“the position is wrong”);
(*P).data P->data
P
data next
(*P).next P->next
free(P)释放P所指向的结点空间。
20.09.2019
通信工程学院
链表的基本操作
创建链表 求链表长度 插入链点 删除链点 查找链点
20.09.2019
通信工程学院
链表的创建(算法2.5/2.6)
data
next
数据域
20.09.2019
指针域
通信工程学院
链式存储的线性表
Head
头节点 头指针
a1
……
length
链表长度(节点数目)
an
tail
链表尾
所以,由链点及链点相互间的链接构成链表。
如果每个链点只包含一个指针域,则此链表 为线性链表或单链表。
20.09.2019
通信工程学院
例:线性表(ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG)
数组长度因为增加了一个新元素而加一
};
补充:(考虑需要补充的情况)
a.位置已满,放不进去新元素
b.元素放入位置不正确(i<1或i>n)
20.09.2019
通信工程学院
顺序表的插入算法
(1)判断线性表的存储空间是否已满,若已满,则进行 “溢出”处理。
(2)检查i值是否超出所允许的范围(1≤i≤n+1),若超 出,则进行“超出”处理。
}node_type ; 链点的定义
typedef struct list_type{
node_type *head;
node_type *tail;
int length;
}list_type;
链表的定义
20.09.2019
通信工程学院
单链表使用注意
P=(LNode*)malloc(sizeof(LNode)); 通过按结点的类型向系统申请建立一个新结点
/*存放线性表元素的数组,关系隐含*/
int len;
/*表示线性表的长度*/
}sqlist;
/* sqlist是数据类型,此处表示线性表的顺序存储结构*/
20.09.2019
通信工程学院
V数组下标
内存
0
a1
1
a2
顺
序
表 n-1
an
的
图
示 Maxsize -1
20.09.2019
元素序号
数据元素不是简单类型时,
一.求线性表的长度(算法 2.1 )
int lenth(sqlist *L) {int lenth; lenth=(*L).len; return(lenth); /*返回线性表的长度*/ }
20.09.2019
通信工程学院
顺序表的基本运算
二、插入运算(算法 2.2)
线性表的插入运算是指在线性表的第i个数据元素之前插入一 个新的数据元素,使长度为n的线性表 (a1, …, ai-1, ai, …, an) 变为长度为n+1的线性表 (a1, …, ai-1, X ,ai, …, an)
20.09.2019
通信工程学院
线性表上常用的运算
⑺删除线性表中的第i个数据元素 ⑻表置空 ⑼查找表中第i个元素的前驱 ⑽查找表中第i个元素的后继 ⑾按一个或多个数据项值的递增或递减 次序重新排列线性表中的数据元素
20.09.2019
通信工程学院
顺序存储结构的特点
在逻辑上相邻的 数据元素,如果 它们的物理位置 也是邻接的。即 线性关系利用物 理上的相邻关系 来体现,叫做顺 序表。
(3)将线性表的第i个元素和它后面的所有元素均后移一个 位置。
(4)将新的数据元素写入到空出的下标为i-1的位置上。 (5)线性表的长度增加1
20.09.2019
通信工程学院
插入运算程序
void insert (list, x, i) {
if (list. n+1 > m) error(1);
else{
存储地址 数据域 指针域
头指针
H 31
1
LI
43
7
QIAN
13
13
SUN
1
19
WANG NULL
25
WU
37
31
ZHAO
7
37
ZHENG
19
43
ZHOU
25
ZHAO ZHOU
20.09.2019
QIAN
SUN
WU
ZHENG
通信工程学院
LI WANG ^
链表的定义
typedef struct node_type{ elemtype data; struct node_type * next;
需要移动大量的节点,平均N/2次的搬移
线性表的大小在声明数组时固定,无法更改。 ——————因此引入链表形式的存储结构: (离散存放,用指针来表示元素之间的关系)
20.09.2019
通信工程学院
链式存储的线性表
分配一些任意的存储单元来存储线性表中的数 据元素,这些单元可以是连续的,也可以是离 散的。这样的存储单元(称为结点)包括两个 域:数据域和指针域。
} }
20.09.2019
通信工程学院
删除算法的算法效率
假设删除第i个元素的概率为qi,所需移动 数据元素的平均次数为:
n
Ed qi ni i1
若
认
为 qi
1 n
则 E d
1 n
n
(n i)
i1
n 2
T n O n
20.09.2019
通信工程学院
顺序表上的基本运算