数构个人笔记 第五课 差缺补漏
对顺序表的差缺补漏
清空顺序表
void ClearList(table t){
t.length = 0;
printf("线性表已清空\n");
}
销毁顺序表
void DestroyList(table t){
ClearList(t);
free(t.head);
t.head = NULL;
printf("线性表已销毁\n");
}
求顺序表长度
int ListLength(table t){
return t.length;
}
判断顺序表是否为空
int ListEmpty(table t){
if(t.length)
return 1;
else return 0;
}
对单链表的查缺补漏
单链表的两种建立方法
头插法
- 从一个空表开始,重复读入数据
- 生成新节点,将读入数据存放到新节点的数据域中
- 从最后一个结点开始,依次将各节点插入到链表的前端
link * initlink(){
link * p = (link*)malloc(sizeof(link));
link * b = (link*)malloc(sizeof(link));
b -> elem = 6;
b -> next = NULL;
p -> next = b;
link *temp = p;
for(int i = 5; i >= 1;i--){
link * a = (link*)malloc(sizeof(link));
a -> elem = i;
a -> next = temp->next;
temp -> next = a;
}
}
时间复杂度为O(n)
后插法
就是我们之前使用的方法
- 从一个空表开始,将新节点逐个插入到链表的尾部,尾指针r指向链表的尾结点
- 初始时,r同表头L均指向头节点。每读入一个数据元素则申请一个新节点,将新节点插入到尾结点后,r指向新节点
link * initLink(){
link * p = (link*)malloc(sizeof(link));//创建头节点
link * temp = p;//创建指针,头节点为初始值
for (int i = 1;i<=5;i++){//创建链表内容
link *a = (link*)malloc(sizeof(link));//用函数malloc创建类型为link的空间装数据
a -> elem =i;
a -> next = NULL;
temp ->next =a;//指针的下一项指向a
temp = temp -> next;//将指针移到a的位置
}
return p;
}
单链表的相关Q&A
讨论1:如何表示空表?
答:无头节点时,头指针为空时表示空表;有头节点时,当头节点的指针域为空时表示空表
讨论2:在链表中设置头节点有什么好处?
答:
- 便于首元结点的处理,首元结点的地址保存在头节点的指针域中,所以在链表的第一个位置上的操作和其他位置一致,无须进行特殊处理;
- 便于空表和非空表的统一处理,无论链表是否为空,头指针都是指向头节点的非空指针,因此空表和非空表的处理也就统一了。
讨论3:头节点的数据域内装的是什么?
答:头节点的数据域可以为空,也可以存放线性表长度等附加信息,但次节点不能计入链表长度值
单链表的特点
- 节点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻
- 访问时只能通过头指针进入链表,并通过每个节点的指针域,依次向后顺序扫描其余节点(顺序存取法),所以寻找第一个节点和最后一个结点所花费的时间不等
顺序表可以随机存取,链表只能顺序存取
链式存储结构的优点
- 节点空间可以动态申请和释放
- 数据元素的逻辑次序靠结点的指针来指示,插入和删除时不需要移动数据元素
链式存储结构的缺点
- 存储密度小,每个节点的指针域需额外占用存储空间。当每个节点的数据域所占字节不多,指针域所占存储空间的比重显得很大
- 存储密度是指节点数据本身所占存储量和整个节点结构中所占的存储量之比
- 链式存储结构是非随机存取结构。对任一节点的操作都要从头指针依指针链查找到该节点,这增加了算法的复杂度
判断链表是否为空
int linkEmpty(link *p){
link * temp = p;
temp = temp -> next;
if(temp)
return 0;
else
return 1;
}
这里用了万能头
#include <bits/stdc++.h>
using namespace std;
后依然报错,经过排除发现,是因为c对函数声明有要求,必须在主函数之前声明过才能正常读取到,如果放在主函数后面则会报错
销毁单链表
link *destroyLink(link *p){
link * temp ;
while(p){
temp = p;
p = p->next ;
free(temp);
}
}
两个递增的单链表合并成一个单链表
link *merge(link *A,link*B){
link *p = (link *)malloc(sizeof(link));
link *pa = p;
A = A -> next;
B = B -> next;
while(A != NULL && B != NULL){
if(A->elem < B->elem){
pa -> next = A;
A = A -> next;
}
else{
pa -> next = B;
B = B -> next;
}
pa = pa -> next;
}
if (A != NULL )pa -> next = A;
else pa -> next = B;
return p;
}