1. 程式人生 > >快慢指標判斷單鏈表中是否有環

快慢指標判斷單鏈表中是否有環

快慢指標中的快慢指的是移動的步長,即每次向前移動速度的快慢。例如可以讓快指標每次沿連結串列向前移動2,慢指標每次向前移動1次。判斷單鏈表是否為迴圈連結串列:讓快慢指標從連結串列頭開始遍歷,快指標向前移動兩個位置,慢指標向前移動一個位置;如果快指標到達NULL,說明連結串列以NULL為結尾,不是迴圈連結串列。如果 快指標追上慢指標,則表示出現了迴圈。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>

using namespace std;

int num;

struct Node{
	int x;
	Node* next;
	Node(int x):x(x),next(NULL) {}
};

Node* createNode(Node* &root,vector<int> &a){
	int n=a.size();
	if(n==0){
		cout<<"資料錯誤"<<endl;
		return root=NULL;
	}else{
		root = new Node(a[0]);
		Node *p=root;
		for(int i=1;i<n;i++){
			Node *r=new Node(a[i]);
			p->next=r;
			p=r;
		}
		return root;
	}
}
/*
可以利用快慢指標的思想來解答
當快慢指標相遇時說明有環
當快指標到達NULL是說明沒有環 
*/
bool hasCycle(Node *head)
{
	Node *root=head;
	if(root == NULL || root->next == NULL)
		return 0;
	else
	{
		Node *fast=root;
		Node *slow=root;
		while( fast != NULL && fast->next != NULL)
		{
			fast=fast->next->next;
			slow=slow->next;
			if(fast == slow)
				return 1;
		}
		if(fast == NULL || fast->next == NULL)
			return 0;
	}
}

int main(){
	vector<int> v; 
	cout<<"請輸入節點個數"<<endl;
	cin>>num;
	for(int i=1;i<=num;i++){
		int a;
		cin>>a;
		v.push_back(a);
	}
	Node *node;
	Node *root=createNode(node,v);
	
	if(hasCycle(root)){
		cout<<"存在環"<<endl;
	}else{
		cout<<"不存在環"<<endl;
	}
	return 0;
}