在O(1)時間刪除鏈表結點

題目描述

給定單向鏈表的頭指針和一個節點指針,定義一個函數在O(1)時間刪除該節點。

編程思路

首先要分析要刪除的結點所在的位置,一共有三種可能:頭結點(鏈表只有一個結點),尾結點,中間結點。
如果鏈表只有一個結點,則刪除鏈表的頭結點(也是尾結點),就需要把鏈表的頭結點設置爲NULL。
如果鏈表有多個結點,要刪除尾結點時,就需要從鏈表的頭結點開始,順序遍歷得到該結點的前序結點,然後將前序結點的next設爲空。
如果刪除的是中間的普通結點,由於是單向鏈表,結點中沒有指向前一個結點的指針,所以只能從頭結點開始順序查找,比較耗時。但我們可以 很方 便的得到要刪除結點的下一個結點,因此,可以換種思路,就是把下一個結點的內容複製到要刪除的節點上,覆蓋原有的內容,再把下一個 結點刪除 就可以。

時間複雜度

鏈表有n個結點,對於n-1個非尾結點而言,我們可以在O(1)時間把下一個結點的內存複製覆蓋要刪除的結點,並刪除下一個結點;對於尾結點而言,由於仍然需要順序查找,時間複雜度是O(n),因此總的平均時間複雜度是[(n-1)*O(1) +O(n)]/n,結果還是O(1)。

程序代碼(Java語言)

package 刪除鏈表結點;

public class Test {
	
	public static class ListNode {
		public int data;
		public ListNode next;
		public ListNode(int data,ListNode next) {
			this.data = data;
			this.next = next;
		}
	}
	
	public static void deleteNode(ListNode node,ListNode head) {
		if(node.next == null) {   
			while(head.next != node) {
				head = head.next;
			}
			head.next = null;
		} else if(head == node) {  
			head = null;
		} else { 
			node.data = node.next.data;
			node.next = node.next.next;
		}
	}

	public static void main(String[] args) {
		ListNode tail = new ListNode(1,null);
		ListNode b = new ListNode(2,tail);
		ListNode a = new ListNode(3,b);
		ListNode head = new ListNode(4,a);
		deleteNode(b,head);
		while(head != null) {
			System.out.println(head.data);
			head = head.next;
		}
	}

}


發佈了35 篇原創文章 · 獲贊 2 · 訪問量 7403
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章