线性表
线性表属于逻辑结构。线性表的顺序存储称为顺序表,链式存储称为链表。也就是说,线性表既可以用顺序存储方式实现,又可以用链式存储方式实现。
顺序表
cpp
// 顺序表中元素类型,这里定义为int
typedef int ElemType;
// 定义顺序表的最大长度
const int maxn = 1000;
typedef struct SqList {
ElemType data[maxn];
int length = 0; // 顺序表当前长度
} Sqlist;线性与非线性结构
线性结构是一个有序数据元素的集合。常用的线性结构有:线性表,栈,队列,双队列,一维数组,串。
非线性结构,数学用语,其逻辑特征是一个结点元素可能有多个直接前趋和多个直接后继。常见的非线性结构有:二维数组,多维数组,广义表,树(二叉树等)。
传统文本(例如书籍中的文章和计算机的文本文件)都是线性结构,阅读是需要注意顺序阅读,而超文本则是一个非线性结构。在制作文本时,可将写作素材按内部联系划分成不同关系的单元,然后用制作工具将其组成一个网型结构。阅读时,不必按线性方式顺序往下读,而是有选择的阅读自己感兴趣的部分。
在超文本文件中,可以用一些单词,短语或图像作为连接点。这些连接点通常同其他颜色显示或加下划线来区分,这些形式的文件就成为超文本文件。通过非线性结构,可能实现页面任意跳转。
有一个以上根结点的数据结构一定是非线性结构。
头指针与头结点
| 头指针 | 头结点 |
|---|---|
| 头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针 | 头结点是为了操作统一和方便设立的,放在第一元素的节点之前,其数据域一般无意义(也可存放链表长度) |
| 头指针具有标识作用,所以长用头指针冠以链表的名字 | 有了头结点,对在第一元素的节点前插入节点和删除第一节点,其操作与其他节点的操作就统一了 |
| 无论链表表是否为空,头指针均不为空。头指针是链表的必要元素 | 头结点不一定是链表的必要元素 |
链表为空判断
循环链表与单链表的判断主要差异就在于循环判断条件上:
- head->next = null , 单链表为空
- head->next = head, 循环链表为空
链表的定义
cpp
typedef struct Node {
int data;
// C++中下面这个struct可以省略,因为C++中struct和class差不多
// C中不可以省略,所以最好都带上
struct Node* next;
} Node;静态链表
静态链表的实现原理是hash,即通过建立一个结构体数组,并令结构体数组的下标直接表示节点的地址,来达到通过直接访问数组中的元素达到访问节点的效果。另外,由于节点的访问非常方便,因此静态链表是不需要头结点的。
cpp
typedef struct Node {
int data; // 数据域
int next; // 指针域,不再是结构体类型的指针
};
秋叶依剑