Skip to content

线性表

线性表属于逻辑结构。线性表的顺序存储称为顺序表,链式存储称为链表。也就是说,线性表既可以用顺序存储方式实现,又可以用链式存储方式实现。

顺序表

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;	// 指针域,不再是结构体类型的指针
};

Released under the MIT License.