链表-环形链表II

42 篇文章 2 订阅
22 篇文章 0 订阅
      力扣题号: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;
}

五、运行结果

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值