2020年2月27日
最近因一些原因導致關於大前端的學習筆記沒有再更新,因爲本人馬上要畢業了,遇到許多煩心事,就業,畢業設計等,總的來說就是一句話,以前的3年半浪費了,所以現在慌了,最好決定先把畢業設計做好,因爲我選的畢業設計和Java的關聯比較多,並且我也是比較喜歡Java的,所以先把這一門好好學學,最近會更新和Java有關的筆記,前端的學習先放一下,不過早晚我會在拾起來的,畢竟我是要做全棧工程師的男人,希望大家不要因此放棄我,O(∩_∩)O!
1.雙向鏈表
1.1雙向鏈表的優缺點
優點:
對於鏈表中一個給定的結點,可以從兩個方向進行操作。在單向鏈表中,只有獲得結點的前驅結點的指針,才能刪除該結點。然而,在雙向鏈表中,即使沒有一個結點的前驅結點的地址,也能刪除該結點(因爲每個結點有都一個指向前驅
結點的指針,可以直接後退到前驅結點)。
主要的缺點:
●每個結點需再添加一個額外的指針,因此需要更多的空間開銷。
●結點的插人或刪除更加費時(需要更多的指針操作)。
1.2雙向鏈表的類型聲明
public class DLLNode{
private int data;
private DLLNode next;
private DLLNode previous;
public DLLNode(int data){
this.data = data;
}
public void setData(int data){
this.data = data;
}
public int getData(){
return data;
}
public void setNext(DLLNode next){
this.next = next;
}
public DLLNode getNext(){
return this.next;
}
public void setPrevious(DLLNode previous){
this.previous = previous;
}
public DLLNode getPrevious(){
return this.previous;
}
}
1.3插入結點代碼
DLLNode DLLInsert(DLLNode headNode, DLLNode nodeToInsert, int position){
if(headNode == null)
//最初鏈表爲空時插入
return nodeToInsert;
int size = getDLLLength(headNode);
if(position > size+1 || position < 1){
System.out.println("插入位置無效 " + "有效插入位置爲 1至"+(size+ 1));
return headNode;
}
if(position == 1){//在鏈表開頭插入
nodeToInsert. setNext(headNode);
headNode. setPrevious(nodeToInsert);
return nodeToInsert;
}else{
//在鏈表中間或末尾插入
DLLNode previousNode = headNode;
int count = 1;
while(count < position-1){
previousNode = previousNode.getNext();
count++;
}
DLLNode currentNode = previousNode.getNext();
nodeToInsert.setNext(currentNode);
if(currentNode != null)
currentNode.setPrevious(nodeToInsert);
previousNode.setNext(nodeToInsert);
nodeToInsert.setPrevious(previousNode);
}
return headNode;
}
時間複雜度爲O(n)。在最差情況下,需要在鏈表的尾部插入結點。
空間複雜度爲0(1),用於創建臨時變量。
1.4刪除結點代碼
DLLNode DLLDelete(DLLNode headNode, int position){
int size = getDLLLength(headNode);
//如果被刪除位置不在鏈表長度範圍內,報錯並返回
if(position > size || position < 1){
System.out. println("該刪除位置無效,有效位置爲 1至"+size);
return headNode;
}
if(position == 1){// 刪除鏈表的第一個結點
DLLNode currentNode = headNode.getNext();
headNode = null;
currentNode.setPrevious(null);
return currentNode;
}else{
//刪除中間或表尾結點
DLLNode previousNode = headNode;
int count= 1;
while(count < position-1){
previousNode = previousNode.getNext);
count++;
}
DLLNode currentNode = previousNode.getNext();
DLLNode laterNode = currentNode.getNext();
previousNode.setNext(laterNode);
if(laterNode != null)
//如果被刪除結點的後繼結點不是NULL結點,那麼設置其前驅.
//指針指向被刪除結點的前驅結點
laterNode.setPrevious(previousNode);
currentNode = null;
}
return headNode;
}
2.循環鏈表
在單向鏈表和雙向鏈表中,都採用NULL值表示鏈表的結束。然而,循環鏈表沒有
結束標誌。當遍歷循環鏈表時需要特別小心,否則將會無限地遍歷鏈表,因爲在循環鏈表中每個結點都有一個後繼結點。
注意:與單向鏈表不同,循環鏈表中沒有next指針爲NULL的結點。循環鏈表在某
些情況下是非常有用的。例如,當多個進程需要在相同的時間內使用同一個計算機資源(CPU)時,必須確保在所有其他進程使用這些資源完前,沒有進程訪問該資源(輪詢算法)。