题目总览
- 从尾到头打印单链表
- 删除一个无头单链表的非尾节点
- 在无头单链表的一个节点前插入一个节点
- 单链表实现约瑟夫环
- 逆置/反转单链表
- 单链表排序(冒泡排序&快速排序)
- 合并两个有序链表,合并后依然有序
- 查找单链表的中间节点,要求只能遍历一次链表
- 查找单链表的倒数第n个节点,要求只能遍历一次链表
思路及代码
从尾到头打印单链表
递归法,若当前节点不为空,在打印当前节点前打印上一个节点。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
删除一个无头单链表的非尾节点
将当前节点的内容改为下个节点的内容,释放下个节点,让当前节点指向下下个节点。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在无头单链表的一个节点前插入一个节点
新建一个节点保存当前节点的内容,并指向下一个节点。
将当前节点改为插入的内容,指向新节点。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
单链表实现约瑟夫环
- 接收一个环形链表的头指针地址,将头指针改为剩下的最后一个节点。
- 处理空链表。
- 用一个节点指针指向头节点,当前节点的下一节点不是当前节点(节点数大于一),循环,当前节点为第一个节点,走 n-1 步,指向第n个节点,删除当前节点。
- 将初始头指针赋值最后节点。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
逆置/反转单链表
- 头插法,建立新链表,用 cur 指向旧链表头结点。
- 循环,用 tmp 保存要拿下来的原链表头结点 cur, cur 指向下一节点,将 tmp 放到新链表的头部(tmp的下一节点指向新链表头结点,再将新链表的头结点改为 tmp),直到 cur 为 NULL。
- 将原链表头指针改为新链表。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
单链表排序(冒泡排序)
- 接收一个普通单链表,处理空链表和只有一个节点的情况。
- 用 tail 指示一次冒泡的终点,第一次要全排,赋值为NULL。
- 循环冒泡比较,每次比较(交换)后,cur 和 next 都指向它们的下一个节点,直到 next == tail。交换中,修改交换标记 exchange。
- 外层循环,用 cur 表示比较的第一个节点,用 next 表示比较的下一个节点,exchange 记录是否交换,一趟比较没有交换,说明已排好,直接返回。每趟比较之后,此次最后一个值已经为最大,tail 前移一个节点。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
合并两个有序链表,合并后依然有序
方法一
- 新链表段接法
- 接收两个链表指针,处理有空链表的情况。
- 创建新链表头指针,指向两链表头节内值点较小的的节点。
- 循环,节点小的指针后移,直到节点下一节点大于另一指针或节点为空,tmp 保存下一节点,当前节点指向另一指针,当前指针赋值为 tmp,如果当前指针为 NULL,说明合并完成,结束循环。
- 返回新链表头指针。
- 可以总是让 p1 指向小的,p2 指向大的,循环挪 p1,接完后再把小的给 p1,大的给 p2。可以不用比较。(原方法 else 是复制 if 后,1 和 2 换,其实更简单,看起来多)
思路图
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
方法二
- 新链单节点表尾插法
- 新建 newList = NULL, 循环,每次比较两指针内容,保存小的节点,小节点指针后移,小节点尾接到 newList。
- 如果有一个指针为 NULL,另一个指针尾接到 newList,返回 newList。
方法三
- 介于上两个方法之间,以头结点小的为 newList,另一个链表每次拿下一个节点接到 newList 的合适位置,直到其中一个指针为空。
查找单链表的中间节点,要求只能遍历一次链表
- 快慢指针法,初始快指针、慢指针都是头指针。
- 循环,如果快指针能走两步(快指针的下一个节点和下下一个节点不为空),快指针走两步,慢指针走一步。
- 返回慢指针。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
查找单链表的倒数第n个节点,要求只能遍历一次链表
- 当节点数少于n时,NULL。
- 快慢指针法,创建返回指针 ret ,快指针先走 n-1 步(此时 ret 为快指针的倒数第 n 个节点)或到 NULL 为止。
- 循环,快指针的下一个节点不为空,快指针和 ret 都向后走一步。
- 返回返回指针。