1. 程式人生 > >單鏈表是否有環(Java版)

單鏈表是否有環(Java版)

題目:判斷一個帶頭結點的單鏈表L是否有環

解題思路:
咋看之下,這題還真不好解,於是又一些投機取巧的人,在訪問單鏈表中元素的時候,用一個比較大的數N控制訪問元素的個數,他們認為如果在訪問到第N個元素之前有一個元素為null,那麼單鏈表沒有環,反之,單鏈表有環。他們的解釋是都訪問了這麼多元素了,還沒有一個元素為空,單鏈表很有可能有環,再加上一般單鏈表中的元素都不超過N個,所以單鏈表有環。對於這種解答方式,我們也只能呵呵了。

要判斷單鏈表有沒有環,肯定會判斷兩個指標是否相等。而且這兩個指標從頭結點位置開始走的步數肯定不一樣。可以設兩個指標slow,fast,slow從頭結點開始往後走,每次走一步,同時fast從頭結點開始往後走,每次走兩步,這兩個指標一直往後面走直到fast為空,則單鏈表無環,或者slow與fast相等,則單鏈表有環。這個過程可以保證slow會走過所有在它之前的結點,同時fast比slow多走的步長從1開始每次遞增1,而且當它們相遇時多走的步長就是環中結點的個數的正整數倍。

ADT定義:

//單鏈表的結點類
class LNode{
	//為了簡化訪問單鏈表,結點中的資料項的訪問許可權都設為public
	public int data;
	public LNode next;
}

演算法實現:
public class LinkListUtli {
	public static boolean hasCircle(LNode L)
	{
		if(L==null) return false;//單鏈表為空時,單鏈表沒有環
		if(L.next==null) return false;//單鏈表中只有頭結點,而且頭結點的next為空,單鏈表沒有環
		LNode p=L.next;//p表示從頭結點開始每次往後走一步的指標
		LNode q=L.next.next;//q表示從頭結點開始每次往後走兩步的指標
		while(q!=null) //q不為空執行while迴圈
		{
			if(p==q) return true;//p與q相等,單鏈表有環
			p=p.next;
			q=q.next.next;
		}
		return false;
	}
}

拓展:判斷帶頭結點的單鏈表是否有環,並找出環的入口結點

解題思路:

不妨設從頭結點到環的入口結點需要走a步即環外包括頭結點在內總共有a個結點,環中有b個結點,假設slow走了s步後,slow與fast第一次相遇。它們肯定是在環內相遇,而且相遇時slow沒有從環的入口結點再次走到環的入口結點,假設在環中距離環入口結點d步長距離相遇,設相遇結點為meet。

此時令頭結點指向fast,讓slow與fast每次往後走一步,當它們再次第一次相遇時,相遇的結點就是環的入口結點。

證明如下:

當slow再走s步後會再次到meet結點,而此時fast走了s步後也會首次到達meet結點,它們相遇,因為兩者都是每次同時走一步,那麼從fast進入環中開始,fast與slow就一直相遇,它們首次相遇的結點就是環的入口結點。

public class LinkListUtli {
	//當單鏈表中沒有環時返回null,有環時返回環的入口結點
	public static LNode searchEntranceNode(LNode L)
	{
		if(L==null) return null;//單鏈表為空時,單鏈表沒有環
		if(L.next==null) return null;//單鏈表中只有頭結點,而且頭結點的next為空,單鏈表沒有環
		LNode p=L.next;//p表示從頭結點開始每次往後走一步的指標
		LNode q=L.next.next;//q表示從頭結點開始每次往後走兩步的指標
		while(q!=null) //q不為空執行while迴圈
		{
			if(p==q) break;//p與q相等,單鏈表有環
			p=p.next;
			q=q.next.next;
		}
		if(q==null) return null;

		//這裡之所以沒有向上面一樣,先讓p,q走一步再進入迴圈判斷,是因為頭結點可能就是環的入口結點
		q=L;
		while(q!=null)
		{
			if(p==q) return p;//返回環中入口結點
			p=p.next;
			q=q.next;
		}
		return null;
	}
}

拓展:判斷帶頭結點的單鏈表是否有環,並求環的長度

解題思路:

設一個指標q指向環入口結點,讓q往後移動直到q再次等於環的入口結點,此時q所走的總步數就是環的長度

public class LinkListUtli {
	//當單鏈表中沒有環時返回null,有環時返回環的入口結點
	public static LNode searchEntranceNode(LNode L)
	{
		if(L==null) return null;//單鏈表為空時,單鏈表沒有環
		if(L.next==null) return null;//單鏈表中只有頭結點,而且頭結點的next為空,單鏈表沒有環
		LNode p=L.next;//p表示從頭結點開始每次往後走一步的指標
		LNode q=L.next.next;//q表示從頭結點開始每次往後走兩步的指標
		while(q!=null) //q不為空執行while迴圈
		{
			if(p==q) break;//p與q相等,單鏈表有環
			p=p.next;
			q=q.next.next;
		}
		if(q==null) return null;

		//這裡之所以沒有向上面一樣,先讓p,q走一步再進入迴圈判斷,是因為頭結點可能就是環的入口結點
		q=L;
		while(q!=null)
		{
			if(p==q) return p;//返回環中入口結點
			p=p.next;
			q=q.next;
		}
		return null;
	}
	
	//求單鏈表環的長度
	public static int circleLength(LNode L)
	{
		LNode p=searchEntranceNode(L);//找到環的入口結點
		if(p==null) return 0;//不存在環時,返回0
		LNode q=p.next;
		int length=1;
		while(p!=q)
		{
			length++;
			q=q.next;
		}
		return length;//返回環的長度
	}
}


相關推薦

單鏈是否Java

題目:判斷一個帶頭結點的單鏈表L是否有環 解題思路: 咋看之下,這題還真不好解,於是又一些投機取巧的人,在訪問單鏈表中元素的時候,用一個比較大的數N控制訪問元素的個數,他們認為如果在訪問到第N個元素之

單鏈就地逆置Java

題目:有一個線性表(a1,a2,a3,...,an),採用帶頭節點的單鏈表L儲存,設計一個演算法將其就地逆置,線性表變為(an,...a3,a2,a1)。所謂“就地”指輔助儲存空間為O(1)。

hash海量查詢字串java

 雜湊表(散列表)是一種非常高效的查詢資料結構,在原理上也與其他的查詢不盡相同,它迴避了關鍵字之間反覆比較的繁瑣,而是直接一步到位查詢結果。當然,這也帶來了記錄之間沒有任何關聯的弊端。應該說,散列表對於那些查詢效能要求高,記錄之間關係無要求的資料有非常好的適用性。注意對雜

【LeetCode-面試演算法經典-Java實現】【142-Linked List Cycle II單鏈II

原題   Given a linked list, return the node where the cycle begins. If there is no cycle, retu

資料結構基礎------1.線性單鏈的建立與輸出方法Java

基礎知識: 線性表(linear list),是其組成元素間具有線性關係的一種線性結構。 線性表有 ①順序儲存結構(sequential storage structure) 順序儲存結構可以簡單的理解利用為 陣列 的形式來進行儲存資料。 ②鏈式儲存結構(ch

演算法之判斷一個單鏈是否

思路:如果一個單鏈表中有環,用一個指標去遍歷,永遠不會結束,所以可以用兩個指標,一個指標一次走一步,另一個指標一次走兩步,如果存在環,則這兩個指標會在環內相遇,時間複雜度為O(n)。 拓展問題1:如果單鏈表有環,找出環的入口節點(環的連線點)。 這裡先證明一個

輸出單鏈中倒數第k個結點Java

題目:輸入帶頭結點的單鏈表L,輸出該單鏈表中倒數第k個結點。單鏈表的倒數第0個結點為該單鏈表的尾指標。要求只能遍歷一次單鏈表。 解題思路: 如果不要求只能遍歷一次單鏈表,我們可以先遍歷一次單鏈表

Java演算法:判斷單鏈是否

README 單鏈表是否有環,這是一個挺有意思的問題,這裡我並沒有提出新的解法,而是解釋了現有的解法,幫助新人和自己理解。 題目描述 判斷一個單鏈表是否有環,如果有,返回第一個環內的節點的引用,如果沒有環,返回nuill。 程式設

Java判斷單鏈是否的兩種實現方法

http://blog.jobbole.com/106227/ 方法一:首先從頭節點開始,依次遍歷單鏈表的每一個節點。每遍歷到一個新節點,就從頭節點重新遍歷新節點之前的所有節點,用新節點ID和此節點之前所有節點ID依次作比較。如果發現新節點之前的所有節點當中存

資料結構之單鏈的增刪改查java

talk is cheap,show you zhe code; /* * 單鏈表的遍歷是從第0個節點開始 沿著next鏈,一次訪問每個節點並且每個節點只能訪問一次 * 當頭結點head為空時 此連結串列為空連結串列 * * 插入操作 * 1空

Java語言 檢測單鏈是否

true ava nis sca 語言 har 判斷 emp ret /** * 判斷鏈表是否有環 * @author Administrator * */public class P238 { public static void main(String[] arg

11.判斷單鏈是否

兩個指針 next 測試 重載 else reader sta clas 復雜度 判斷單鏈表是否有環: 這裏也是用到兩個指針,如果一個鏈表有環,那麽用一個指針去遍歷,是永遠走不到頭的。 因此,我們用兩個指針去遍歷:first指針每次走一步,second指針每次走兩步

劍指Offer面試題15Java:鏈中倒數第K個結點

head 計數器 easy sta 相同 ret white style 輸出 題目: 輸入一個鏈表。輸出該鏈表中倒數第k哥結點。 為了符合大多數人的習慣,本題從1開始計數。即鏈表的尾結點是倒數第1個結點。 比如一個鏈表有6個結點。從頭結點開始它們的值依次是1。2。

判斷單鏈是否

plc .html weibo app sin pla mpc html cnblogs 辜鈉魯u0ri0忌蠱負http://huiyi.docin.com/txqq_8fb449e9c9儼夾銥43gi1鑰倚蚜http://www.docin.com/app/user/us

如何判斷一個單鏈是否

算法 查找 public class LinkedListRing{ static class LinkedNode<T>{ private T t ; private LinkedNode<T> next = null; public LinkedNode(T t)

單鏈是否問題

開始 數字 info ptc data 下一個 nbsp 有環 ret 小咖是某計算機專業的學生。linglingling,伴隨這鈴聲,同學們都準時來上課了。 老師:這節課是計算機課,我們學習了單鏈表,請同學說一下什麽是單鏈表。 同學們紛紛舉起了手。好,小白你來說

JS-單鏈是否以及的入點問題

給定一個連結串列,判斷連結串列中是否有環。 進階: 你能否不使用額外空間解決此題? 方案1 雜湊表 雜湊表是最容易理解的一個方案 建立一個雜湊表,如果不存在就向雜湊表中新增資料,存在的話就直接返回true(存在的可能只有P點,同時P點也是環的入點(這個和下一道題

單鏈是否入口點【轉】

1.限制與要求 不允許修改連結串列結構。 時間複雜度O(n),空間複雜度O(1)。 2.思考 2.1判斷是否有環 如果連結串列有環,那麼在遍歷連結串列時則會陷入死迴圈,利用這個特徵,我們可以設計這樣的演算法。 使用一個slow指標,一個fast指標。 slow

判斷單鏈是否,如果找出的入口位置=>求兩個相交連結串列的交點

首先如何判斷一個連結串列是否有環: 設定兩個指標(fast, slow),初始值都指向頭,slow每次前進一步,fast每次前進二步,如果連結串列存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。(當然,fast先行頭到尾部為NULL,則為無環連結串列

筆試題:判斷一個單鏈是否,如果,找出的起始位置

</pre><pre name="code" class="cpp">Node * FindLoop(Node *phead) { Node *p = phead,q = phead,h = phead; while(p && q->next)