学单链表的时候,是不是一到插入删除就犯迷糊?明明知道要用指针,可那些指针左指右指的,怎么都理不清头绪。写的代码要么插入后链表断了,要么删除后程序直接崩了,别提多让人着急了。其实啊,单链表的插入删除,关键就是把指针的指向弄明白。今天兔子哥就用大白话给你讲讲,指针在单链表中是咋实现插入删除的,保证新手也能看明白,一起往下看吧!
先搞懂单链表的节点和指针关系
单链表就像一节节连起来的火车车厢,每节车厢就是一个 “节点”。每个节点里不光有数据,还有个指针,这个指针就像挂钩,用来连接下一节车厢。
咱们先定义一个节点看看:
c运行
struct Node {int data; // 节点里的数据struct Node *next; // 指向 next 节点的指针};这里的
next指针特别重要,它存着下一个节点的地址,正是靠它,所有节点才能串成一条链。比如有三个节点,第一个的next指向第二个,第二个的next指向第三个,第三个的next指向NULL(表示到尾巴了)。那链表的头指针又是啥?头指针
head就像火车头,它指向链表的第一个节点。要是链表是空的,head就指向NULL。插入节点:关键是 “先连后断”,别把链搞断了
插入节点分好几种情况:插在表头、插在中间、插在表尾。不管哪种,核心都是调整指针的指向,而且顺序不能错。
1. 插在表头
最简单的一种,比如原来链表是:head -> A -> B -> NULL,现在要插个新节点 C 在最前面。
步骤很简单:
- 让新节点 C 的
next指向原来的第一个节点 A(C->next = head) - 让头指针
head指向新节点 C(head = C)
这样新链表就变成:head -> C -> A -> B -> NULL
代码大概是这样:
c运行
// 创建新节点struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));newNode->data = 10; // 新节点的数据// 插入表头newNode->next = head; // 新节点连原来的头head = newNode; // 头指针改指新节点2. 插在两个节点中间
比如要把 C 插在 A 和 B 中间,原来 A->next 是 B,现在得让 A->next 指向 C,C->next 指向 B。
关键是先让新节点连后面,再让前面的节点连新节点,顺序反了就麻烦了。
步骤:
- 找到要插入位置的前一个节点(这里是 A)
- 新节点 C 的
next指向 A 原来的下一个(C->next = A->next) - A 的
next指向新节点 C(A->next = C)
为啥要这顺序?要是先让 A->next 指向 C,那 B 的地址就丢了,新节点就没法连 B 了,链表就断了。
3. 插在表尾
就是让最后一个节点的
next指向新节点,新节点的next指向NULL。步骤:
- 找到最后一个节点(
next为NULL的那个) - 最后一个节点的
next指向新节点(last->next = newNode) - 新节点的
next设为NULL(newNode->next = NULL)
删除节点:别忘了 “释放内存”,不然会泄漏
删除节点也分删表头、删中间、删表尾,核心是把要删的节点 “摘” 下来,同时保证前后节点能连上。
1. 删除表头节点
原来 head -> A -> B -> NULL,要删 A。
步骤:
- 先用一个临时指针
temp记下 A 的地址(temp = head) - 头指针
head指向 A 的下一个节点 B(head = head->next) - 释放
temp指向的内存(free (temp))
这一步很重要,不释放会造成内存泄漏。
2. 删除中间节点
比如要删 A 和 B 之间的 C,原来 A->next = C,C->next = B。
步骤:
- 找到要删除节点 C 的前一个节点 A
- 让 A 的
next直接指向 B(A->next = C->next) - 释放 C 的内存(free (C))
这样 A 就直接连 B 了,C 就被摘下来了。
3. 删除表尾节点
要删最后一个节点 B,原来 A->next = B,B->next = NULL。
步骤:
- 找到 B 的前一个节点 A
- 把 A 的
next设为NULL(A->next = NULL) - 释放 B 的内存(free (B))
插入和删除的对比:指针操作有啥不同?
| 操作 | 相同点 | 不同点 | 最容易错的地方 |
|---|---|---|---|
| 插入 | 都要调整指针指向 | 要先连新节点,再改前节点的指针 | 顺序搞反导致链表断裂 |
| 删除 | 都要保证链表不断开 | 要先记下删除节点地址,再改前节点的指针 | 忘了释放内存,造成泄漏 |
你可能会问,怎么找插入或删除位置的前一个节点啊?得靠指针遍历。比如用一个指针
p从头开始,p = p->next一步步往后挪,直到找到目标位置。兔子哥刚开始学的时候,总记不住指针操作的顺序,后来想了个笨办法:拿张纸画出来,每个节点画个框,指针用箭头表示,插入删除的时候就跟着箭头改方向,画明白了再写代码,就不容易错了。
其实单链表的插入删除不难,难的是一开始对指针指向的变化不敏感。多写几遍代码,每次操作前都想想 “这个指针现在指哪,改了之后指哪”,慢慢就有感觉了。别害怕犯错,错了就调试,看看指针到底指到哪去了,调着调着就会了。
最后想说,指针是单链表的灵魂,把指针的指向搞清楚,链表操作就像搭积木一样简单。刚开始慢没关系,练熟了自然就快了,希望这些能帮到你!
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~