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),再次相遇即爲環入口。