- 单链表的删除操作(删除 p 所指结点的后继结点)
- 步骤:
① 用临时指针q指向待删除的后继结点:q = p->next;
② 修改p的指针,跳过待删除结点:p->next = p->next->next;
③ 释放q所指结点的内存:free(q); - 注意:必须确保
p不为NULL且p->next不为NULL,否则无法删除后继。
- 步骤:
void DeleteAfter(ListNode* p) {
if (p == NULL || p->next == NULL) return; // 防止空指针
ListNode* q = p->next;
p->next = q->next;
free(q);
}
- 单链表的查找运算(函数 Find_List)
- 功能:在带头结点的单链表中查找第
k个元素(从1开始计数),若存在则返回该结点指针,否则返回NULL。 - 核心逻辑:
① 从头结点的下一个结点(第一个实际元素)开始遍历
② 使用计数器i记录当前是第几个元素
③ 当i == k或链表结束时停止循环
④ 返回对应结点或NULL
- 功能:在带头结点的单链表中查找第
ListNode* Find_List(ListNode* L, int k) {
if (L == NULL || k < 1) return NULL;
ListNode* p = L->next; // 第一个元素结点
int i = 1;
while (p != NULL && i < k) {
p = p->next;
i++;
}
return p; // 若找到第k个则返回p,否则返回NULL
}
- 单链表的插入运算(函数 Insert_List)
- 功能:将新元素
newElem插入到第k个元素之前(即插入后成为新的第k个元素) - 成功返回
0,失败返回-1 - 核心逻辑:
① 若k == 1,前驱为头结点L
② 否则查找第k-1个结点p
③ 若p存在,则创建新结点s,将其插入到p之后
④ 新结点指向原p->next,再更新p->next指向s
- 功能:将新元素
int Insert_List(ListNode* L, int k, ElemType newElem) {
if (L == NULL || k < 1) return -1;
ListNode* p = L;
// 查找第k-1个结点(若k=1,则直接使用头结点)
for (int i = 1; i < k; i++) {
p = p->next;
if (p == NULL) return -1; // 第k-1个结点不存在
}
// 创建新结点
ListNode* s = (ListNode*)malloc(sizeof(ListNode));
if (s == NULL) return -1; // 内存分配失败
s->data = newElem;
s->next = p->next;
p->next = s;
return 0; // 插入成功
}
实现单链表的头插法和尾插法是构建链表的两种基本方式,分别用于将新结点插入到链表头部或尾部。
1. 头插法(Head Insertion)
- 特点:每次将新结点插入到链表的最前端(即头结点之后),最终链表中元素的顺序与输入顺序相反。
- 适用场景:不关心元素顺序时快速建表,如栈式结构。
- 步骤:
① 创建新结点s
② 将s->next指向原第一个元素(即L->next)
③ 更新头结点的指针:L->next = s
void HeadInsert(ListNode* L) {
ElemType x;
ListNode* s;
// 假设以输入 -1 结束
while (scanf("%d", &x) && x != -1) {
s = (ListNode*)malloc(sizeof(ListNode));
if (s == NULL) return; // 内存分配失败
s->data = x;
s->next = L->next; // 新结点指向原第一个结点
L->next = s; // 头结点指向新结点
}
}
2. 尾插法(Tail Insertion)
- 特点:每次将新结点插入到链表的末尾,保持元素的输入顺序。
- 适用场景:需要保持数据原始顺序时使用,如队列式结构。
- 步骤:
① 创建新结点s
② 使用尾指针rear记录链表最后一个结点
③ 将rear->next指向s,然后更新rear = s
void TailInsert(ListNode* L) {
ListNode *s, *rear = L; // rear 始终指向尾结点
ElemType x;
// 假设以输入 -1 结束
while (scanf("%d", &x) && x != -1) {
s = (ListNode*)malloc(sizeof(ListNode));
if (s == NULL) return; // 内存分配失败
s->data = x;
s->next = NULL;
rear->next = s; // 当前尾结点指向新结点
rear = s; // 更新尾指针
}
}
完整示例初始化(带头结点)
ListNode* InitList() {
ListNode* L = (ListNode*)malloc(sizeof(ListNode));
L->next = NULL;
return L;
}


3104

被折叠的 条评论
为什么被折叠?



