链表双指针的应用
在一个链表里使用两个指针,可以实现一些操作
如寻找链表中倒数第K个结点,寻找中间位置结点,判断链表有没有环,以及如何找到环的入口
#include <stdio.h>
#include<stdlib.h>
typedef struct Node
{
int Data;
struct Node* PNext;
}Node;
typedef Node* PNode;
int CountNum;
void CreateNode(PNode* List)//创建一个链表,且赋值从0开始
{
Node* NewNode = (Node*)malloc(sizeof(Node));
if (!NewNode) exit(1);
NewNode->PNext = NULL;
NewNode->Data = CountNum++;
(*List)->PNext = NewNode;
*List = NewNode;
}
//寻找倒数第K个结点,第一个指针先走k步,然后第二个再走,第一个走到终点第二个指针就指向倒数第k个
int Last_But_K(PNode HNode,int k)
{
int count = 0;
PNode p=HNode;
while (count < k)
{
count++;
HNode = HNode->PNext;
}
while (HNode)
{
HNode = HNode->PNext;
p = p->PNext;
}
return p->Data;
}
//同理一个走一步,一个走两步
int Middle(PNode HNode)
{
PNode p = HNode;
while (p && p->PNext)
{
p = p->PNext->PNext;
HNode = HNode->PNext;
}
return HNode->Data;
}
//链表里面可能有环结构,利用双指针可以判断链表里面是否有环,同时可以找到环的入口
//判断有没有环,一个指针走一步,一个指针走两步,如果第一个指针到达尾部则说明没有环,如果两个指针相遇则说明有环,且有环必相遇
int If_Circle(PNode HNode)
{
PNode p1, p2;
p1 = p2 = HNode;
while (1)
{
if (p1 && p1->PNext)p1 = p1->PNext->PNext;
else return 0;
p2 = p2->PNext;
if (p1 == p2) return 1;
}
}
//如果有环,找到环的入口,采取的方法又是一个指针走一步,另一个指针走两步,当两个指针相遇的时候
//p2比p1多走一圈,令p2再回到起点与p1都是一步一步地走,相遇处就是入口
//起点到入口的距离和相遇点到入口的距离相等
PNode Find_Entrance(PNode HNode)
{
PNode p1, p2;
p1 = p2 = HNode;
do
{
p1 = p1->PNext->PNext;
p2 = p2->PNext;
} while (p1 != p2);
p1 = HNode;
while (p1 != p2)
{
p1 = p1->PNext;
p2 = p2->PNext;
}
return p1;
}
int main()
{
PNode HNode;
HNode = (PNode)malloc(sizeof(Node));
HNode->PNext = NULL;
PNode List = HNode;
for (int i = 0; i < 5; i++) CreateNode(&List);
PNode Node1 = List;
for (int i = 0; i < 9; i++) CreateNode(&List);
//printf("%d\n", Last_But_K(HNode, 3));
List->PNext = Node1;
printf("%d\n", Middle(HNode));
if (If_Circle(HNode))
{
PNode pEnce = Find_Entrance(HNode);
printf("%d", pEnce->Data);
}
}

浙公网安备 33010602011771号