力扣题号:142. 环形链表 II
一、题目描述
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
二、示例
三、求解思路
这道题目,不仅考察对链表的操作,而且还需要一些数学运算。
主要考察两知识点:
- 判断链表是否环
- 如果有环,如何找到这个环的入口
四、代码实现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Lnode {
int data;
struct Lnode* next;
}Lnode, * Linklist;
// 创建环1 头节点
void create_ring1(Linklist& L) {
if (L == NULL) {
return;
}
Lnode* pre = NULL;
Lnode* cur = L;
while (cur) {
pre = cur;
cur = cur->next;
}
pre->next = L;
}
// 创建环2 中间节点
void create_ring2(Linklist& L) {
if (L == NULL) {
return;
}
Lnode* pre = NULL;
Lnode* cur = L;
Lnode* pos = NULL;
while (cur) {
pre = cur;
if (cur->data == 5) {
pos = cur;
}
cur = cur->next;
}
pre->next = pos;
}
// 判断环和查找入口
Lnode* judgment_ring(Linklist& L) {
Lnode* fast = L;
Lnode* slow = L;
Lnode* index1 = NULL;
Lnode* index2 = NULL;
while (fast != NULL && fast->next != NULL) {
fast = fast->next->next;
slow = slow->next;
if (slow == fast) { // 判断环
index1 = fast;
index2 = L;
while (index1 != index2) { // 找到环的入口
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return NULL;
}
/*
头插法插入链表
*/
bool headInsert(Linklist& L, int x) {
Lnode* newnode = (Lnode*)malloc(sizeof(Lnode));
if (newnode == NULL) {
return false;
}
newnode->data = x;
newnode->next = L;
L = newnode;
return true;
}
// 打印链表
void print(Linklist L) {
if (L == NULL) {
return;
}
int n = 0;
while (L) {
if (n++ > 20) {
break;
}
printf("%3d", L->data);
L = L->next;
}
printf("\n");
}
int main() {
// 创建链表
Linklist L = NULL;
headInsert(L, 1);
headInsert(L, 2);
headInsert(L, 3);
headInsert(L, 4);
headInsert(L, 5);
headInsert(L, 6);
headInsert(L, 7);
printf("Linklist 1:\n");
print(L);
// 创建链表
Linklist L1 = NULL;
headInsert(L1, 1);
headInsert(L1, 2);
headInsert(L1, 3);
headInsert(L1, 4);
headInsert(L1, 5);
headInsert(L1, 6);
headInsert(L1, 7);
// 创建环
create_ring1(L1);
printf("Linklist 2:\n");
print(L1);
// 创建链表
Linklist L2 = NULL;
headInsert(L2, 1);
headInsert(L2, 2);
headInsert(L2, 3);
headInsert(L2, 4);
headInsert(L2, 5);
headInsert(L2, 6);
headInsert(L2, 7);
// 创建环
create_ring2(L2);
printf("Linklist 3:\n");
print(L2);
// 判断环和入口
Lnode* node = NULL;
node = judgment_ring(L);
if (node != NULL) {
printf("Linklist 1 is ring, pos-data is %2d\n\n", node->data);
}
else {
printf("Linklist 1 is not ring\n\n");
}
node = judgment_ring(L1);
if (node != NULL) {
printf("Linklist 2 is ring, pos-data is %2d\n\n", node->data);
}
else {
printf("Linklist 2 is not ring\n\n");
}
node = judgment_ring(L2);
if (node != NULL) {
printf("Linklist 3 is ring, pos-data is %2d\n\n", node->data);
}
else {
printf("Linklist 3 is not ring\n\n");
}
return 0;
}