資料結構與演算法 鍊錶2 雙向鍊錶

2021-08-14 02:43:35 字數 3827 閱讀 4915

雙向鍊錶結點和單向鍊錶結點的區別在於,多了乙個指向前驅的指標。當這個節點是第乙個節點時,前驅指標是乙個空指標。

單向鍊錶的結構如下圖1所示:

圖1 單向鍊錶結構圖

雙向鍊錶的結構如下圖2所示:

圖2 雙向鍊錶結構圖

顯然通過以上2個圖的對比,可以看出鍊錶兩種形式的特點。雙向鍊錶顯然我們在建立的時候需要永久維護的是first和last資訊,要是鍊錶不為空,first指向的是初始的鏈結點,last指向的是表尾的鏈結點(當只有乙個鏈結點的時候,first和last指向同乙個);初始鏈結點的prev指向null,鏈尾的鏈結點next指向null。

對雙向鍊錶的基本操作有插入、刪除和非空,其中插入有insertfirst()即在首位插入新的鏈結點、insertlast()即在末尾插入新的鏈結點、insertafter()即在某一元素值後插入新的鏈結點;同理刪除有deletefirst()、deletelast()和deletekey()。這幾個插入和刪除方法,單純的靠想象是很難的,在敲寫**的時候我們應該結合圖,看著圖示來寫邏輯,要不然繞來繞去一會兒就寫懵了。

首先鏈結點link應有的屬性如下**所示:

/**

* 鏈結點

*/public class link

}

對doublelinklist初始時有:

/**

* 雙向列表

*/public class doublelinkedlist

/***從隊尾插入鏈結點

** @param data

*/public void insertlast(int data)

//等等其他對雙向鍊錶的操作方法

}

首先是非空判斷,顯然當first==null時說明鍊錶中沒有鏈結點,**:

/**

* 鍊錶是否為空

** @return

*/public boolean isempty()

2.insertfirst()從首位插入新的鏈結點,先畫圖,圖示如下:

圖3 表頭插入

根據圖示敲**邏輯,具體如下:

/**

* 插入乙個鏈結點

** @param data

*/public void insertfirst(int data) else

first = newlink;

}

3.insertlast()從表尾插入新的鏈結點,邏輯和表頭插入比較相似,**如下:

/**

* 從隊尾插入鏈結點

** @param data

*/public void insertlast(int data) else

last = newlink;

}

4.deletefirst()刪除操作,刪除操作就是從雙向鍊錶中拿出第乙個結點,返回值型別為link:

/**

* 刪除第乙個結點

** @return

*/public link deletefirst() else

first = current.next;//無論是只有乙個結點(只有乙個的話first =null) 多個結點當前要刪除的結點的下乙個都是為第乙個

return current;

} else

}

5.deletelast()刪除表尾結點,返回值型別也是link:

/**

* 刪除最後乙個結點

** @return

*/public link deletelast() else

last = current.previous;

return current;

} else

}

以上操作相對簡單,依然是敲**的時候畫圖理解。

6.insertafter(int  key,int  data)在某一要素結點後插入新的結點,要處理的東西比較多,圖4中有比較好的解釋:

圖4  某結點current後插入新的結點

首先我們要找到要出入的位置,之後處理前後結點的問題,**如下:

/**

* 在指定結點後面插入新的data元素結點

** @param key 根據key找到指定結點

* @param data 要插入的新結點

*/public string insertafter(int key, int data)

}if (current == last) else

newlink.previous = current;

current.next = newlink;

return "insert succeed";

}

我設定的返回值型別是string,根據鍊錶的情況返回不同的處理資訊。

7.deletekey(int  key)根據key值找到對應的結點,然後處理刪除結點之後的前後結點關係:

/**

* 根據關鍵元素值 刪除對應的鏈結點

** @param key

* @return

*/public link deletekey(int key)

}//2.說明找到key對應的鏈結點 current 刪除之

if (current == first) else if (current == last) else

//todo 以上**可以優化成以下形式 可能稍微難理解一點 假設要刪除的點是首位 current.previous就是null

// if (current == first) else

//// if (current == last) else

return current;

}

8.就是從頭到尾遍歷整個鍊錶以及從尾到頭遍歷整個鍊錶的寫法:

/**

* 從頭往後遍歷整個鍊錶

*/public void showallfromfirst()

} else

system.out.println("\n");

}/**

* 從尾到頭遍歷整個鍊錶

*/public void showallfromlast()

} else

system.out.println("\n");

}

測試類:

/**

* 雙向鍊錶測試

*/public class doublelinkedlisttest

}

輸出結果:

以上**,如有問題請大家及時指出。關於單向鍊錶請在此鏈結中檢視資料結構之鍊錶1_單鏈表及基本概念。

資料結構與演算法(4)雙向鍊錶

1.單鏈表的的缺點 1 單向鍊錶查詢的方向只能是乙個方向,而雙向鍊錶可以向前或者向後查詢 2 單向鍊錶不能自我刪除,需要考輔助節點,而雙向鍊錶則可以進行自我刪除 2.雙向鍊錶的說明 1 遍歷 和單向鍊錶一樣,只是可以向前,可以向後 2 新增 預設新增到雙向鍊錶的最後 3 修改 和單向鍊錶思路一樣 4...

演算法2 鍊錶3 雙向鍊錶

雙 向 鍊錶中有兩條方向不同的鏈,即每個結點中除next域存放後繼結點位址外,還增加乙個指向其直接前趨的指標域prior。雙向鍊錶在查詢時更方便 特別是大量資料的遍歷。注意 雙鏈表由頭指標head惟一確定的。帶頭結點的雙鏈表的某些運算變得方便。將頭結點和尾結點鏈結起來,為雙 向 迴圈鍊錶。形式描述 ...

資料結構四雙向鍊錶

雙向鍊錶也叫雙鏈表,是鍊錶的一種,它的每個資料結點中都有兩個指標,分別指向直接後繼和直接前驅。所以,從雙向鍊錶中的任意乙個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。而之前的單鏈表為單向鍊錶,雙向鍊錶也就是在單鏈表的結點中增加乙個指向其前驅的pre指標。如圖 這裡介紹雙向鍊錶的常用操作 l ...