補充4:單鏈表的應用

1.排序

	public Node sort(){
		Node nextnode = null;
		Node curnode = head;
		int temp = 0;

		while(curnode.next!=null){
			nextnode = curnode.next;
		while(nextnode!=null){
			if(curnode.data>nextnode.data){
				temp = curnode.data;
				curnode.data = nextnode.data;
				nextnode.data = temp;
			}
			nextnode = nextnode.next;
		}
		curnode = curnode.next;
		}
		return head;
	}

2.反轉

反轉完全可以套用排序,只需交換數據即可,刪除判斷

	public Node reverse(){
		Node nextnode = null;
		int temp = 0;
		Node curnode = head;
		
		while(curnode.next!=null){
			nextnode = curnode.next;
		while(nextnode!=null){			
				temp = curnode.data;
				curnode.data = nextnode.data;
				nextnode.data = temp;			
			nextnode = nextnode.next;
		}
		curnode = curnode.next;
		}
		return head;
	}

3.查找中間節點數值

採用快慢指針方式,快指針一次走兩步,慢指針一次走一步,當快指針走完時,慢指針所在位置剛好是鏈表的中間位置

	public Node mid(){
		Node quick = this.head;
		Node slow = this.head;
		while(quick!=null&&quick.next!=null&&quick.next.next!=null){
			quick = quick.next.next;
			slow = slow.next;
		}
		System.out.println("mid data:"+slow.data);
		return slow;
	}

4.查找倒數第K個位置節點的數值

同樣是採用兩個指針,P1先走K步,然後P1,P2一起走,當P1到達尾部是P2所在位置即倒數第K的位置

	public Node FindK(int k){
		if(k<1||k>length()){
			return null;
		}
		Node P1 = this.head;
		Node P2 = head;
		for(int i=0;i<=k-1;i++)
			P1 = P1.next;
			while(P1!=null){
				P1 = P1.next;
				P2 = P2.next;
			}		
			System.out.println("data:"+P2.data);
			return P2;
	}

5.刪除重複節點

    還是採用兩個指針來標記,兩個指針在開始時均指向頭節點,當第二個節點與頭節點數據一致時,P2指向第三個節點再與頭節點進行比較,如果數據不一致則P2與P1又同時指向第三個節點了,以此類推一直到結束。

	public void deleterepeat(){
		Node P1 = head;
		while(P1!=null){
			Node P2 = P1;
			while(P2.next!=null){
				if(P1.data==P2.next.data){
					P2.next = P2.next.next;
				}else{
					P2 = P2.next;
				}
			}
			P1 = P1.next;
		}
	}

6.從未到頭輸出單鏈表,遞歸方式

	public void reverseprint(Node rehead){
		if(rehead!=null){
			reverseprint(rehead.next);
			System.out.println(rehead.data);
		}
	}

傳遞的參數是Node類的所以在主程序中定義一個

                Node rehead = link.head;
		System.out.println("reverseprint:");
		link.reverseprint(rehead);

7.判斷鏈表是否有環,有環的情況下找出環的入口

    如果一個單鏈表有環,則尾節點相同。藉助於兩個指針,一個快一個慢,一直向前走,如果某一時刻兩個指針重疊了,就說明該鏈表有環。

	public boolean IsLoop(Node node){
		Node fast = head;
		Node slow = head;
		if(fast==null){
			return false;
		}
		while(fast!=null&&fast.next!=null){
			fast = fast.next.next;
			slow = slow.next;
			if(fast == slow){
				System.out.println("isloop");
				return true;
			}
		}
		return!(fast==null||fast.next==null);
	}

    找出環的入口

首先在兩指針相遇說明有環,並且停下一快一慢的循環,讓慢的指針回到起點和快的指針一起向前一步一步走,當兩指針再次相遇的地方就是環的入口。

	public Node Findloopenter(Node node){
		Node fast = head;
		Node slow = head;
		if(fast==null){
			return null;
		}
		while(fast!=null&&fast.next!=null){
			fast = fast.next.next;
			slow = slow.next;
			if(fast == slow){
				break;
			}
		}
		if(fast==null||fast.next==null){
			return null;
		}
		
		slow = head;
		while(slow!=fast){
			slow = slow.next;
			fast = fast.next;
		}
		return slow;
	}

解釋一下爲什麼這樣就可以找到入口


head到入口的距離爲L,環的周長爲R,因爲fast是slow的二倍,所以slow沒有走完環時就會和fast相遇,相遇時slow在環內走了K,因此

fast = L+n*R+k

slow = L+K

fast從開始直到相遇一直是slow的兩倍,所以L+n*R+k = 2*( L+K)

解得L=(n-1)*R+(R-K)

(n-1)*R是整數

此時讓slow從頭再走L,fast走(R-K),再次相遇即爲環入口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章