数据结构-线性表的链式表示
1.结点是什么?
2.什么是链表?
3.解释一下单链表、双链表、循环列表的含义,用图表示出来。
4.什么为头指针、头结点、首元结点
———————————————————————————————————————————-
1.结点包括 数据域与指针
2.链表 为n 个结点由指针链组成的一个链表
3.1单链表:结点只有一个指针域
头节点 → [数据1, 指针] → [数据2, 指针] → ... → [数据n, null]
Plain Text
只能单向遍历,从头节点开始,通过指针依次访问后续节点
尾节点的指针指向 null
。
3.2双链表:结点有两个指针域的链表
null ←→ [null, 数据1, 指针] ←→ [前驱, 数据2, 后继] ←→ ... ←→ [前驱, 数据n, null]
Plain Text
- 支持双向遍历,可从头节点或尾节点开始。
- 头节点的前驱指针和尾节点的后继指针通常指向
null
。
3.3循环链表
与单链表类似,但尾节点的指针指向头节点,形成环
头节点 → [数据1, 指针] → [数据2, 指针] → ... → [数据n, 指针] → 头节点
Plain Text
- 若需频繁反向遍历,选双链表。
- 若需循环访问,选循环链表。
- 若追求简单高效,选单链表。
4.1头指针:指向链表的第一个结点的指针
作为链表的入口,用于定位和访问整个链表。无论链表是否为空,头指针始终存在(为空链表时,头指针指向 null
)。
4.2首元结点:链表中第一个存储实际数据的结点
存储链表的第一个有效数据,是链表中数据部分的起点。
4.3 头结点
- 定义:位于首元结点之前的一个 “空节点”,不存储实际数据(或仅存储链表长度等辅助信息)。
- 作用:简化链表的插入、删除操作(尤其是在首元结点位置操作时),避免对 “空链表” 和 “非空链表” 的特殊处理。
头指针 → 头结点 → 首元结点 → 其他节点 → ... → 尾节点 → null
[辅助信息] [数据1] [数据2] [数据n]
Plain Text
单链表的存储结构有两种表示形式
如果用Lnode来的话
#include <stdio.h>
#include <stdlib.h>
typedef struct Lnode {
int data;
struct Lnode *next;
} Lnode; // 只定义 Lnode 类型,不使用 LinkList 别名
// 创建一个新节点(返回 Lnode* 类型)
Lnode* CreateNode(int value) {
Lnode* newNode = (Lnode*)malloc(sizeof(Lnode));
if (newNode == NULL) {
printf("内存分配失败\n");
exit(1);
}
newNode->data = value;
newNode->next = NULL;
return newNode;
}
int main() {
// 创建链表(头节点指针)
Lnode* head = NULL; // 头指针,类型为 Lnode*
// 添加节点
head = CreateNode(1); // 第一个节点
head->next = CreateNode(2); // 第二个节点
head->next->next = CreateNode(3); // 第三个节点
// 遍历链表
Lnode* current = head; // 当前节点指针,类型为 Lnode*
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
// 输出: 1 2 3
// 释放内存(避免内存泄漏)
current = head;
while (current != NULL) {
Lnode* temp = current;
current = current->next;
free(temp);
}
return 0;
}
C
如果用*LinkList的话
#include <stdio.h>
#include <stdlib.h>
typedef struct Lnode {
int data;
struct Lnode *next;
} Lnode, *LinkList;
// 创建一个新节点
LinkList CreateNode(int value) {
LinkList newNode = (LinkList)malloc(sizeof(Lnode));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
int main() {
// 创建链表(头指针)
LinkList list = NULL;
// 添加节点
list = CreateNode(1); // 第一个节点
list->next = CreateNode(2); // 第二个节点
list->next->next = CreateNode(3); // 第三个节点
// 遍历链表
LinkList p = list;
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
// 输出: 1 2 3
return 0;
}
C
很明显,LinkList更简单一点,是因为一开始就创建了数组,所以不需要后期家指针*
单链表的各种操作
**单链表的初始化
构造一空表
那么如果是清空链表?