目录
前言
我重新翻了翻顺序表与链表的内容,发现还有一些小疏漏。再看了看今天要复习的内容,觉得有点少,但是今天下午还要做毕设,所以就先复习这么多。
一、前几天的补充
主要就是判断表是否为空。
1、顺序表isEmpty(SqList L)
我想了想,位序1号元素不存在即可判断该顺序表为空。但是我按照这个思路写了一下,发现好像有点行不通。然后我又去看了一下顺序表的结构元素,发现有一个length元素表示该顺序表的长度,所以只需判断 L.length == 0 即可。
2、单链表isEmpty(LinkList L)
链表分为带头节点与不带头节点的形式。不带头节点时,对于单链表 L 来说,只需要判断 L == NULL 即可;对于带头节点的形式时,则是需要判断 L->next == NULL
3、双链表isEmpty(DLinkList L)
双链表与单链表判空的方式一样。
4、销
由于在初始化时大多采用malloc函数来申请内存空间,所以当需要销表时,需要使用free函数来进行表格的销除。若是顺序表的静态分配,系统会自动收回空间,无需free函数。
自此,这三种线性表的基本操作——创销增删改查以及逻辑结构就复习完了。相当于已经会了100以内的加减法,下面要去学1w以内的乘除法了。
二、循环链表
1、循环单链表
描述:尾节点的next指针指向头节点
基本操作方式与单链表基本一致。除了在初始化时,头节点的next指针指向了自己;在删除指定节点时,不需要考虑是否为尾节点的情况。
判空操作只需要看头节点的next指针是否指向自己即可。
2、循环双链表
描述:头节点的prior指针指向尾节点,尾节点的next指针指向头节点
基本操作方式与双链表基本一致。除了初始化时头节点的两个指针都指向自己;删除指定节点时,也不需要考虑是否为尾节点的情况。
判空操作只需要看头节点的两个指针是否指向自己即可。
3、小结
我没有去实现这两个数据结构,因此可能会有不完善的地方。
下面是王道的一张思维导图
三、静态链表
1、静态链表的基本概念
静态链表就是使用数组的形式实现链式存储
typedef int ElemType;
#define MaxSize 10
typedef struct SLNode{
ElemType data; //存储节点的数据元素
int next; //存储后继节点在顺序表中的下标
}SLinkList[MaxSize]; //将SLinkList来表示静态链表
int main() {
SLinkList Slist; //声明一个静态链表Slist
SLNode nodes[MaxSize]; //声明一个节点数组nodes
printf("%d\n", sizeof(SLNode)); //节点大小
printf("%d\n", sizeof(Slist)); //静态链表大小
printf("%d\n", sizeof(nodes)); //静态链表大小
return 0;
}
2、静态链表优缺点
优点:
增、删操作不需要大量移动元素
缺点:
不能随机存取,只能从头结点开始依次往后查找;容量固定不可变
适用场景:
1、不支持指针的低级语言
2、数据元素数量固定不变的场景(如操作系统的文件分配表 FAT)
3、静态链表的基本操作
比较好想懂,所以就不准备实现了。
1、初始化
头节点放在数组 0 号位,next = -1 表示指向NULL。
2、插入
假设插入节点node在链表Slist中的下标为 i ,node的前驱的next赋值给node的next,修改node的前驱的next为 i 。
3、删除
将待删除节点node的next赋值给node的前驱的next。
4、查
遍历查找,当前节点node的下一个节点所在位置为Slist[node.next];若node.next == -1,则表示已经到表尾。
5、改
与查结合,能查到就能改
6、销
若是采用静态分配的方式,则系统会自动收回空间;若采用动态分配的形式,则需要用free函数收回空间。
总结
今天是顺序表、单链表、双链表内容的一个收尾,并补充了解了一些关于循环链表的知识以及静态链表的概念,内容较少。
今天下午可能有事,还要去做毕设,时间非常匆忙。
明天应该是要复习栈的内容,要用顺序存储的方式以及链式存储的方式来实现。也许还会再看一点队列的内容