关于链表已经学了有一段时间了,今天抽空进行了整理,列出来常见的有关链表的面试题,以下想法如有瑕疵望批评指出,希望能给初学者带来一点参考和价值
从尾到头打印单链表
递归打印
1 | // 1、从尾到头打印单链表 递归 |
非递归打印
1 | void ListReveresePrint2(ListNode *Node) |
删除一个无头单链表的非尾结点(不能遍历链表)
核心代码
1 | //2. 删除一个无头单链表的非尾结点(不能遍历链表) |
测试
1 | void TestListDelNotFirst() |
在无头单链表的一个结点前插入一个结点(不能遍历链表)
1 | //3.在无头单链表的一个结点前插入一个结点(不能遍历链表) |
逆置/反转单链表
思路一:
从第二个结点开始,将其删除,人挪活插在第一个结点处,直到链表结束
1 | void listReverse(ListNode **Node) |
思路二:
改变每个结点的指针指向从而逆置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
29void listReverseRePoint(ListNode **Node)
{
if (Node == NULL)
{
return;
}
if (*Node == NULL)
{
return;
}
if ((*Node)->next == NULL)
{
return;
}
ListNode *pre = *Node;
ListNode *cur = (*Node)->next;
pre->next = NULL;
while (cur != NULL)
{
ListNode *temp = cur->next;
cur->next = pre;
pre =cur;
cur = temp;
}
*Node = pre;
}
找出两个链表里相同数据
1 | // 5.找出两个链表里相同数据 |
测试
1 | void TestListInterstion() |
单链表实现约瑟夫环
核心代码
1 | //6.单链表实现约瑟夫环 |
测试
1 | void TestListJosephCircle() |
合并两个有序的链表,合并后依然有序
具体代码
1 | //7.合并两个有序的链表,合并后依然有序 |
测试
1 | void TestMerge() |
查找单链表的中间结点,要求只能遍历一次链表
思路:定义快慢指针,当快指针走完时,慢指针刚好是在中间位置,好比是两人赛跑,跑的快点人的速度是慢的人的二倍
具体代码
1 | //8.查找单链表的中间结点,要求只能遍历一次链表 |
测试
1 | void TestFindMid() |
查找单链表中的倒数第K个结点,要求只能遍历一次链表
思路:定义快慢指针,快指针先走k步,满指针再开始走,快指针走完的时候就是慢指针走到倒数第k个结点处
具体代码
1 | //9.查找单链表中的倒数第K个结点,要求只能遍历一次链表 |
测试
1 | void TestFindTailK() |
删除单链表中的倒数第K个结点
思路:同查找倒数第k个结点一样,我们定义快慢指针进行异步,还需要定义一个pre来记录要删除结点的先驱,删除后需要指向被删除的下一个
具体代码
1 | //10.删除单链表中的倒数第K个结点 |
测试
1 | void TestDelTailK() |