剑指offer 有环链表

链表带环的情况下就需要活用指针:

  • 两个指针的组合可以很好的遍历结点
  • 两个指针的行走速度有差异即可进行环的相关判断(一步、两步、先走后走)
  • 链表每走一步都要注意下一个节点为nullptr时,是否会影响到程序的鲁棒性,造成程序的崩溃,走两步的指针更需要注意这个问题,需要判断两次!(否则为nullptr也就不会再走下去)
#include <iostream>  
#include <string>  
#include <vector>  
#include <stack>
using namespace std;  

typedef int datatype;

struct Node
{
	datatype value;
	Node* Next_Node;
};

struct Node_circle
{
	unsigned int Number;
	Node *entrace;
};

//判断链表中是否有环
Node* Exist_circle(Node *first)
{

	if (first == nullptr || first->Next_Node == nullptr)
	{
		return nullptr;
	}

	Node* Node_temp1 = first->Next_Node;
	Node* Node_temp2 = Node_temp1->Next_Node;

	while (Node_temp2 != nullptr && Node_temp1 != nullptr)
	{

		Node_temp1 = Node_temp1->Next_Node;
		Node_temp2 = Node_temp2->Next_Node;
		//在链表中,每一个节点为nullptr时是否影响到程序的鲁棒性,造成程序崩溃,都必须考虑在内
		if (Node_temp2->Next_Node != nullptr)
		{
			Node_temp2 = Node_temp2->Next_Node;
		}
		
		if (Node_temp1 == Node_temp2)
		{
			return Node_temp1;
			break;
		}
	}
	return nullptr;
}

//输出环中结点的个数以及环的入口
Node_circle* Find_circle(Node *first)
{
	Node* Node_temp5 = Exist_circle(first);
	if (Node_temp5 == nullptr)
	{
		return nullptr;
	}

	int number = 1;
	//已存在环,无需判断下一个节点是否为nullptr了
	Node* Node_temp3 = Node_temp5->Next_Node;
	while (Node_temp3 != Node_temp5)
	{
		Node_temp3 = Node_temp3->Next_Node;
		number++;
	}

	Node* entrace = first;
	for (int i = 0;i<number;i++)
	{
		entrace = entrace->Next_Node;
	}

	Node* Node_temp4 = first;
	while (Node_temp4 != entrace)
	{
		Node_temp4 = Node_temp4->Next_Node;
		entrace = entrace->Next_Node;
	}

	Node_circle* circle_Node;
	circle_Node->Number = number;
	circle_Node->entrace = entrace;

	return circle_Node;
}

void main()  
{     

	system("pause");
}  


猜你喜欢

转载自blog.csdn.net/misayaaaaa/article/details/78577280