
链表和快慢指针的应用
1.寻找链表中间节点
(若为奇数节点的链表,找到最中间的节点;若为偶数节点的链表,找到中间两个后一个节点)
-
(1)方法:快慢指针
( fast指针一次移动两个节点,slow指针一次移动一个节点)
-
(2)代码和解析:
A.创建和初始化链表
(这里没有对malloc进行检查,主要为了避免冗余,对于该代码而言没有太大问题)
LNode* n1 = (LNode*)malloc(sizeof(LNode));
LNode* n2 = (LNode*)malloc(sizeof(LNode));
LNode* n3 = (LNode*)malloc(sizeof(LNode));
LNode* n4 = (LNode*)malloc(sizeof(LNode));
LNode* n5 = (LNode*)malloc(sizeof(LNode));
n1->val = 1;
n2->val = 2;
n3->val = 3;
n4->val = 4;
n5->val = 5;
n1->next = n2;
n2->next = n3;
n3->next = n4;
n4->next = n5;
n5->next = NULL;
B.创建结构体:
typedef struct ListNode
{
int val;
struct ListNode* next;
}LNode;
C.MiddleNode函数的实现:
LNode* MiddleNode(LNode* head)
{
LNode* slow = head;
LNode* fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
fast指针一次移动两个节点,slow指针一次移动一个节点,当fast遍历完所有节点,slow在链表中间(这里要考虑奇数偶数的情况)。

while (fast && fast->next):不论链表节点个数是奇数个还是偶数个,当fast或fast->next为NULL会停止遍历。
-
(3)原码:
#include<stdio.h> #include<stdlib.h> typedef struct ListNode { int val; struct ListNode* next; }LNode; LNode* MiddleNode(LNode* head) { LNode* slow = head; LNode* fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; } return slow; } int main() { LNode* n1 = (LNode*)malloc(sizeof(LNode)); LNode* n2 = (LNode*)malloc(sizeof(LNode)); LNode* n3 = (LNode*)malloc(sizeof(LNode)); LNode* n4 = (LNode*)malloc(sizeof(LNode)); LNode* n5 = (LNode*)malloc(sizeof(LNode)); n1->val = 1; n2->val = 2; n3->val = 3; n4->val = 4; n5->val = 5; n1->next = n2; n2->next = n3; n3->next = n4; n4->next = n5; n5->next = NULL; LNode* ret = MiddleNode(n1); printf("%d\n", ret->val); return 0; }
2.寻找倒数第K个节点
-
(1) 方法:使用快慢指针
这里的“快”意味着fast指针先走k步,slow才开始往前走(fast和slow速度相同:每次一个节点),fast和slow之间始终相差k步(k-1)个节点 。
-
(2)代码和解析:
A.创建结构体和链表:
typedef struct ListNode
{
int val;
struct ListNode* next;
}LNode;
LNode* n1 = (LNode*)malloc(sizeof(LNode));
LNode* n2 = (LNode*)malloc(sizeof(LNode));
LNode* n3 = (LNode*)malloc(sizeof(LNode));
LNode* n4 = (LNode*)malloc(sizeof(LNode));
LNode* n5 = (LNode*)malloc(sizeof(LNode));
n1->val = 1;
n2->val = 2;
n3->val = 3;
n4->val = 4;
n5->val = 5;
n1->next = n2;
n2->next = n3;
n3->next = n4;
n4->next = n5;
n5->next = NULL;
B.FindKthToTail函数的实现:
LNode* FindKthToTail(LNode* head, int k)
{
if (head == NULL)
return NULL;
LNode* slow, *fast;
slow = fast = head;
while (k--)
{
if (fast == NULL)
{
return NULL;
}
fast = fast->next;
}
while (fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
while(k--):循环执行k次,fast走k步;循环结束,fast,slow一起走;在fast=NULL时,循环停止,slow位置(fast和slow之间始终相差k-1个节点 )为倒数第k位置,函数返回所需值ret->val。
-
(3)原码:
#include<stdio.h> #include<stdlib.h> typedef struct ListNode { int val; struct ListNode* next; }LNode; LNode* FindKthToTail(LNode* head, int k) { if (head == NULL) return NULL; LNode* slow, *fast; slow = fast = head; while (k--) { if (fast == NULL) { return NULL; } fast = fast->next; } while (fast) { slow = slow->next; fast = fast->next; } return slow; } int main() { LNode* n1 = (LNode*)malloc(sizeof(LNode)); LNode* n2 = (LNode*)malloc(sizeof(LNode)); LNode* n3 = (LNode*)malloc(sizeof(LNode)); LNode* n4 = (LNode*)malloc(sizeof(LNode)); LNode* n5 = (LNode*)malloc(sizeof(LNode)); n1->val = 1; n2->val = 2; n3->val = 3; n4->val = 4; n5->val = 5; n1->next = n2; n2->next = n3; n3->next = n4; n4->next = n5; n5->next = NULL; LNode* ret = FindKthToTail(n1, 4); printf("%d\n", ret->val); return 0; }

1958

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



