《数据结构用C语言描述》第二章
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
25 34 57 16
63
i
插入x 50
01 23 4 5
48 09 67
25 34 570 50 16 48
09 63 顺序表插入时,平均数据移动次数 AMN在各表项 插入概率相等时平均时间复杂度: T(n)=O(n)
· 删除
25 34 571650 16 48 09 63 删除 x
01 23 4 5 6 7
sequenlist *L, int i )
■{
■ if ( i >= 0 && i < (*L).last) return
(*L).data[i];
■ else
■ printf ( “参数i 不合理! \n” );
· 插入
01 23 4 5 6 7
25 34 57 16
63
i
插入x 50
01 23 4 5
return 0;
//插入不成功
else {
for ( j =( * L ) . l a s t ; j >=i-1; j - - )
(*L).data[j] =(* )L.data[j -1];
(*L).data[i] =x; (*L).last++; }
return 1; //插入成
}
01 23 4 5 6 7
链表(linked List)
链表是线性表的链接存储表示 · 单链表 · 静态链表 · 循环链表 · 双向链表
单链表(Singly linked List)
定义: 用一组地址任意的存储单元存 放线性表中的数据元素。(ZHOU ZHAO
SUN G
存储地址 1 7 13 19
数据域 ZHANG WANG LI ZHAO
r ->next =q; r =q; //插入到表末端
}
r ->next =NULL;
return head;
}
单链表清空
void makeEmpty ( l i n k l i s t head ) {
//删去链表中除表头结点外的所有其它结点
linklist *q; while ( head->next != NULL ) {//当链不空 时, 循环逐个删去所有结点 q = head->next; head->next = q->
while ( (ch =getchar( ) ) != ‘\n’ ) {
q = malloc ( s i z e o f ( l i n k l i s t ) ) ;
q->data =ch;
//建立新结点
q->next = head->next; //插入到表前端
head->next =q;
}
return head;
head
a1
an ^ head ^
非空表
空表
· 单链表的类型定义
typedef char datatype;
typedef struct node { { datatype data;
struct node * next; } linklist;
//链表结点 //结点数据域 //结点链域
l i n k list *head , *p;
)缺点 5 在顺序表中进行插入和删除操作时,需要移动数
据元素,算法效率较低。 6 对长度变化较大的线性表,或者要预先分配较大
空间或者要经常扩充线性表,给操作带来不方便 。 7 原因: 数组的静态特性造成
顺序表之整体概念:
内存状态 elem
0 1
表区
...
变量
elem listsize length
//链表头指针
带表头结点的单链表
• 表头结点位于表的最前端, 本身不带数 据, 仅标志表头。
• 设置表头结点的目的: 表操作的实现。
简化链
head
a1
非空表
an ^ head ^
空表
前插法建立单链表
· 从一个空表开始,重复读入数据: · 生成新结点 · 将读入数据存放到新结点的数据域中 · 将该新结点插入到链表的前端 · 直到读入结束符为止。
{ Insert ( A, x , n ) ; n++; }
}
}
· 集合的“交”运算
void Intersection ( SeqList &A, SeqList &B) {
int n=Length ( A) ;
int m=Length (B) ;
int i =0;
while ( i <n) {
i++; i f ( i <( * L ) . l a s t ) return i ; else return -1; }
■ 求表的长度
■ int Length ( sequenlist *L ) {
return (*L).last+1;
■}
■ 提取函数:在表中提取第i 个元素的
值
datatype Get (
int x =Get( A, i ) ; //在A中取一元素
int k =LOCATE( B, x ) ; //在B中查找它
i f ( k ==-1 ) { Delete ( A, i ) ; n--; }
else i++; }
//未找到在A中删除它
}
4.顺序表的分 1 优点析
2 顺序表的结构简单 3 顺序表的存储效率高,是紧凑结构 4 顺序表是一个随机存储结构(直接存取结构) 2
//成功删除
return 0; }
//表中没有x
25 34 571650 16 48 09 63 删除 x
01 23 4 5 6 7
25 34 57 50 48 09 63
顺序表删除平均数据移动次数AMN在各表项 删除概率相等时:T(n)=O(n)
顺序表的应用:集合的“并”运算
void Union ( SeqList &A, SeqList &B) {
int last;
/ / 当前元素个数
} sequenlist;
sequenlist *L;
顺序表基本运算
· 按值查找: 找x在表中的位置,若查找成功,返回表项的位置,否则返回-1
int LOCATE( sequenlist *L, datatype x ) { int i =0; while ( i <( * L ) . l a s t &&(*L).data[i] != x )
}
后插法建立单链表
· 每次将新结点加在链表的表尾;
· 尾指针r ,总是指向表中最后一个结点, 新结点插 在它的后面;
head ^
^
head ^
r
^
qr
linklist createListR ( )
{ char ch;
l i n k l i s t *head //建立表头结点
l i n k l i s t *q, *r =NULL;
指针域WU W 13 ANG Z1 HAN LI null )
37
25
WU
7
头指针
31
ZHOU
19
37
SUN
25
单链表结构
每个元素由结点(Node)构成, 它包括两 个域: 数据域Data和指针域next
Node
data next
存储结构: 链式存储结构 特点: 存储单元可以不连续 。存取方式: 顺序存取。
{int i , j ;
//在表中删除已有元素x
i =LOCATE ( L , x ) ; //在表中查找x
i f ( i >=0 )
{ (*L).last -- ;
for ( j =i ; j <L . l a s t ; j++ )
(*L).data[j] =(*L).data[j+1];
return 1; }
操作算法
初始化操作 插入操作 删除操作
last-1
查找操作
数组下标 排序操作
空
... ...
......
闲
maxsize-1
顺序表之整体概念:
顺序表有下列缺点: 插入、删除操作时需要移动大量元素,效 率较低; 最大表长难以估计,太大了浪费空间,太 小了容易溢出。 因此,在插入和删除操作是经常性操作的 应用场合选用顺序存储结构不太合适,此 时可以选用链式存储结构,数据元素之间 的逻辑关系由结点中的指针来指示。
除最后一个元素外,其他每一个元 素有一个且仅有一个直接后继。
线性表的基本操作
1 SETNULL(L) 初始化, 构造一个空的线 性表
2 LENGTH(L) 求长度,返回线性表中数据 元素个数
3 GET(L,i) 取表L中第i个数据元素赋值
4 LOCATE(L,x) 按值查找, 若表中存在一个 或多个值为x的结点, 返回第一个找到的数 据元素的位序, 否则返回一个特殊值。
5 INSERT(L,x,i) 在L中第i个位置前插入新的 数据元素x, 表长加1。
6 DELETE(L,i) 删除表中第i个数据元素, e返 回其值, 表长减1。
复杂运算可以通过基本运算的组合实现
• 例: 利用线性表的基本运算实现清除表L中多余的重复结点 • PURGE(Linear_list *L) • {int i=1,j,x,y; while(i<LENGTH(L)) • {x=GET(L,i); • j=i+1; while(j<=LENGTH(L)) • {y=GET(L,j); • if(x==y) DELETE(L,j); • else j++; • } i++; •}
else
{ for ( j =i ; j <=( * L ) . l a s t ; j++ )
(*L).data[j-1] =(*L).data[j];
(*L).last - -;
}
return ( 1 ) ;
/ / 成功删除
}
· 顺序表的删除
int DELETE ( sequenlist *L, datatype x )
第二章 线性表
· 线性表 · 顺序表 · 链表 · 顺序表与链表的比较
线性表
定义: n( 0)个数据元素的有限序列, 记作 (a1, …ai-1, ai, ai+1,…, an) 其中,ai 是表中数据元素,n 是表长度。 特点: 同一线性表中元素具有相同特性。 相邻数据元素之间存在序偶关系。
除第一个元素外,其他每一个元素 有一个且仅有一个直接前驱。
48 09 67
25 34 5570 50 16 48
09 63
· 顺序表的插入
int Insert ( sequenlist *L, datatype x , int i )
{ int j ; //在表中第i 个位置插入新元素x i f ( i <0 | | i >( * L ) . l a s t | | (*L).last >=maxsize-1)
int n =Length ( A) ;
int m=Length ( B ) ;
for ( int i =0; i <m; i++ ) {
int x =Get ( B, i ) ; //在B中取一元素
int k =LOCATE (A, x ) ; //在A中查找它
i f ( k ==-1 )
//若未找到插入它
a1 a2 … ai … …
…
a a+l … a+(i-1)*l … … … a+(n-1)*l idle
顺序表(Sequenlist)的类型定义
#define maxsize 1024 //最大允许长度
typedef int datatype;
typedef struct
{datatype data[maxsize]; //存储空间基址
head= malloc (sizeof ( l i n k l i s t ) ) ;
r=head;
while ( (ch =getchar( ) ) != ‘\n’ ) {
q = malloc ( s i z e o f ( l i n k l i s t ) ) ;
q->data =ch;
//建立新结点
25 34 57 50 48 09 63
· 顺序表的删除
int DELETE ( sequenlist *L, int i )
{int j ;
//在表中删除第i 个元素x
i f ((i<1) | | (i>(*L).last+1))
{printf (“error”); return null; //非法位置
顺序表
定义: 将线性表中的元素相继存放在 一个连续的存储空间中。
存储结构: 数组。 特点: 线性表的顺序存储方式。存取
方式: 顺序存取 顺序存储结构示意图
01 2 3 4 5
45 89 90 67 40 78
顺序表的存储方式:
LOC(ai) =LOC(a1)+(i-1)*l
1 2 … i ……… n
head ^
head
q
^
q
Linklist *createListF ( )
{ char ch; l i n k l i s t *q;
l i n k l i s t *head
//建立表头结点
head= malloc (sizeof ( l i n k l i s t ) ) ;
head->next =NULL;