鏈表——Java實現鏈表反轉的兩種方法

前提

鏈表是多個不一定連續的內存塊(節點),通過節點保存的後置指針或前置指針串聯起來的一種數據結構;
鏈表不支持隨機訪問;
下面的反轉鏈表沒有特別提示的都是帶頭鏈表(引入了哨兵的鏈表),用java實現,節點類如下:

/**
 * @Author Haoqi
 * @Description 鏈表節點
 **/
Class Node{
	int data;
	Node next;
	/**
	 * 構造哨兵節點
	 **/
	public Node() {
        this.data = -1;
        this.next = null;
    }
	//其他構造方法
	//...
}

兩種實現

原地反轉

通過指針的變化,在鏈表自身進行反轉,不會產生另外一個新鏈表;

public static Node reverseLinkList(Node head){
	if(head.next == null){
		return head;
	}
	Node prev = head.next;
	Node pcur = prev.next;
	while(pcur != null){
		prev.next = pcur.next;
		pcur.next = head.next;
		head.next = pcur;
		pcur = prev.next;
	}
	return head;
}
  • head節點是哨兵節點,不存數據只是,只是爲了簡化代碼;
  • 第一個判斷看鏈表是否爲空鏈表,即除了哨兵沒有其他數據節點;
  • 實現需要兩個指針,一個前置指針 prev ,一個移動指針pcur;
  • 循環結束條件是移動指針爲null;
  • 注意指針操作順序防止指針丟失,這裏可以逐步畫圖演示,輔助理解
  • pcur指針指向的是下次循環結束後的第一個數據節點 head.next = pcur;
  • 最後pcur向後移動,但每次循環開始結束prev一直是pcur的前置節點;
  • 時間複雜度O(n)

頭插法反轉

顧名思義,遍歷舊鏈表,反覆向新鏈表的第一個節點位置插入,產生的新鏈表就是舊鏈表的反轉;

public static Node reverseLinkList(Node head){
	if(head.next == null){
		return head;
	}
	Node newHead = new Node();
	Node pcur = head.next;
    Node curNextTmp = null;
	while(pcur != null){
		curNextTmp = pcur.next;
		pcur.next = newHead.next;
		newHead.next = pcur;
		pcur = curNextTmp;
	}
	return newHead;
}
  • head節點是哨兵節點,不存數據只是,只是爲了簡化代碼;
  • 第一個判斷看鏈表是否爲空鏈表,即除了哨兵沒有其他數據節點;
  • 實現需要新建一個帶頭空鏈表newHead,一個移動指針pcur和一個緩存curNextTmp;
  • 循環結束條件是移動指針爲null;
  • 每次循環,先將pcur的後續節點緩存起來,然後再向新鏈表第一個數據節點處插入pcur(頭插),最後將pcur移到緩存的後續節點;
  • 時間複雜度爲O(n)

熄燈

怎麼寫出正確的鏈表?畫圖理解記憶,再多默寫幾次就行。

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