1. 程式人生 > >單鏈表就地逆置(Java版)

單鏈表就地逆置(Java版)

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

解題思路:
如果是順序儲存的話,我們很容易想到解題思路,利用1個輔助變數讓第1個元素與第n個元素交換,然後再利用這個輔助變數讓第2個元素與第n-1個元素交換,...最後利用這個輔助變數讓第n/2個元素與第n+1-n/2個元素交換。


如果不要求“就地”的話,可以建立一個n個元素輔助陣列,一次訪問單鏈表中的每個元素,並存儲到該陣列中,然後再依次訪問單鏈表中的每一個元素,同時從該陣列的末尾開始為單鏈表中的元素賦值,直到陣列第1個元素的值賦值給單鏈表最後一個元素。


如果單鏈表為空或單鏈表中只有頭結點,那麼單鏈表不需要逆置,如果單鏈表中只有一個元素,逆置之後它的位置還是不會改變,所以可以不逆置。當單鏈表中有2個或兩個以上的元素時,從第1個元素斷開,令它的next為空,依次訪問第2個元素到第n個元素,當訪問到其中的任意一個元素時,將它插入到頭結點之後,也就是把它插入到第1個位置,這樣原始的第1個元素就會被後面的n-1個元素插入到它的前面,原始的第2個元素就會被後面的n-2個元素插入到它的前面,...直到原始的第n個元素插入到第1個位置。這樣就實現了帶頭結點的單鏈表的就地逆置。

ADT定義:

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

演算法實現:
public class LinkListUtli{
	public static void reverse(LNode L){
		//單鏈表為空或只有頭結點或只有一個元素,不用進行逆置操作
		if(L==null||L.next==null||L.next.next==null)
			return;
		LNode p=L.next.next;//令p指向線性表中第2個元素a2 
		L.next.next=null;//令線性表中第1個元素a1的next為空
		while(p!=null){
			LNode q=p.next;
			//將p插入頭結點之後
			p.next=L.next;
			L.next=p;
			p=q;//繼續訪問下一個元素
		}
		
	}
}