基于Java實現雙向鏈表
本文實例為大家分享了Java實現雙向鏈表的具體代碼,供大家參考,具體內容如下
雙向鏈表與單鏈表的對比:
1、單向鏈表查找只能是一個方向,雙向鏈表可以向前或者向后查找
2、單向鏈表不能自我刪除,需要靠輔助節(jié)點**(即需要通過找到要刪除的節(jié)點的前一個節(jié)點,通過該節(jié)點進行刪除的操作,而雙向鏈表只需找到要刪除的節(jié)點就行了)**。雙向鏈表可以自我刪除
雙向鏈表示意圖
分析(代碼實現原理):temp為輔助節(jié)點(因為頭節(jié)點不可動)
1、遍歷:方式與單鏈表一致,但是是雙向的,可以向前,也可以向后
2、添加(默認添加到最后面)
(1)先找到鏈表的最后一個節(jié)點
(2)temp.next=newnode
(3)newnode.pre=temp
3、修改:思路與原理與單鏈表一致
4、刪除:
(1)因為是雙向鏈表,可以自我刪除該節(jié)點
(2)找到要刪除的節(jié)點,假設這個節(jié)點為temp
(3)temp.pre.next=temp.next
(4)temp.next.pre=temp.pre
添加節(jié)點(按順序):
步驟:
(1)找到要添加節(jié)點位置的前一個節(jié)點(temp)
(2)node.next=temp.next
(3)temp.next.pre=node
(4)temp.next=node
(5)node.pre=temp
代碼實現:
public class DoubleLinkedList { ?? ? //創(chuàng)建頭結點。表示鏈表的頭 ?? ?private Node Head=new Node(0,"",""); ?? ? ?? ?//返回頭結點 ?? ?public Node getHead() { ?? ??? ?return Head; ?? ?} ?? ?//AddNode1:添加節(jié)點到單鏈表的尾部 ?? ?//思路:當不考慮節(jié)點順序 ?? ?//1、找到鏈表的最后一個節(jié)點 ?? ?//2、將最后這個節(jié)點的Next指向新節(jié)點 ?? ?public void AddNode1(Node node) { ?? ??? ?//因為頭節(jié)點不能動,所以需要一個輔助節(jié)點遍歷 ?? ??? ?Node temp=Head; ?? ??? ?while(true) { ?? ??? ??? ?//找到鏈表的最后一個節(jié)點 ?? ??? ??? ?if(temp.next==null) { ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ??? ?//否則temp=temp的下一個節(jié)點 ?? ??? ??? ?temp=temp.next; ?? ??? ??? ? ?? ??? ?} ?? ??? ?//循環(huán)出來之后,temp是最后一個節(jié)點 ?? ??? ?temp.next=node; ?? ??? ?node.pre=temp; ?? ?} ?? ? ?? ?//AddNode2:添加節(jié)點,按順序 ?? ?public void AddNode2(Node node) { ?? ??? ?//因為頭結點不能動,所以需要一個輔助節(jié)點遍歷,找到添加新節(jié)點的位置 ?? ??? ?Node temp=Head; ?? ??? ?boolean flag=false; //用于標識鏈表中是否已經存在新節(jié)點的順序 ?? ??? ?while(true) { ?? ??? ??? ?//如果該節(jié)點是最后一個節(jié)點,則新節(jié)點添加到最后一個位置 ?? ??? ??? ?if(temp.next==null) { ?? ??? ??? ??? ?break; ?? ??? ??? ?}else if(temp.next.number>node.number) { //說明找到了添加新節(jié)點的位置 ?? ??? ??? ??? ?break; ?? ??? ??? ?}else if(temp.next.number==node.number) { //說明新節(jié)點的順序已經存在在鏈表中 ?? ??? ??? ??? ?flag=true; ?? ??? ??? ?} ?? ??? ??? ?temp=temp.next; ?? ??? ?} ?? ??? ?if(flag) { ?? ??? ??? ?System.out.println("該節(jié)點的順序已經存在,插入失敗"); ?? ??? ?}else { ?? ??? ??? ?//則說明新節(jié)點在鏈表中不存在,插入新節(jié)點 ?? ??? ??? ?//新節(jié)點的下一個節(jié)點=輔助節(jié)點的下一個節(jié)點 ?? ??? ??? ?node.next=temp.next; ?? ??? ??? ?if(temp.next!=null) { ? //如果temp的下一個節(jié)點不為空,則temp的下一個節(jié)點的前一個節(jié)點為新節(jié)點 ?? ??? ??? ??? ?temp.next.pre=node; ?? ??? ??? ?} ?? ??? ??? ?//輔助節(jié)點的下一個節(jié)點=新節(jié)點 ?? ??? ??? ?temp.next=node; ?? ??? ??? ?//新節(jié)點的前一個節(jié)點為輔助節(jié)點 ?? ??? ??? ?node.pre=temp; ?? ??? ?} ?? ??? ? ?? ?} ?? ? ?? ?//刪除節(jié)點 ?? ?public void remove(Node node) { ?? ??? ?if(Head.next==null) { ?? ??? ??? ?System.out.println("鏈表為空!"); ?? ??? ??? ?return; ?? ??? ?} ?? ??? ?//創(chuàng)建輔助節(jié)點 ?? ??? ?Node temp=Head.next; ?? ??? ?boolean flag=false; //標識是否找到了要刪除的節(jié)點 ?? ??? ?while(true) { ?? ??? ??? ?if(temp==null) { //遍歷完鏈表了 ?? ??? ??? ??? ?break; ?? ??? ??? ?}else if(temp.number==node.number) { //找到要刪除的節(jié)點了 ?? ??? ??? ??? ?flag=true; ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ??? ?temp=temp.next; ?? ??? ?} ?? ??? ?if(flag) { //鏈表中存在要刪除的節(jié)點 ?? ??? ??? ? ?? ??? ??? ??? ?temp.pre.next=temp.next;?? ?//令temp的前一個節(jié)點的下一個節(jié)點為temp的后一個節(jié)點 ?? ??? ??? ??? ?if(temp.next!=null) { ? ? ? //如果temp不為最后一個節(jié)點的話 ?? ??? ??? ??? ??? ?temp.next.pre=temp.pre; ? ?//令temp的下一個節(jié)點的前一個節(jié)點為temp的前一個節(jié)點 ?? ??? ??? ??? ?} ?? ??? ??? ? ?? ??? ?}else { ?? ??? ??? ?System.out.printf("不存在編號為%d的節(jié)點",node.number); ?? ??? ?} ?? ?} ?? ? ?? ?//修改節(jié)點,按照節(jié)點的Number來修改 ?? ?public void update(Node newNode) { ?? ??? ?if(Head.next==null) { ?? ??? ??? ?System.out.println("鏈表為空!"); ?? ??? ??? ?return; ?? ??? ?} ?? ??? ?//創(chuàng)建輔助節(jié)點,對鏈表遍歷,知道找到等于修改節(jié)點的number的時候 ?? ??? ?Node temp=Head.next; ?? ??? ?boolean flag=false; //用來標識是否找到了修改節(jié)點的Number ?? ??? ?while(true) { ?? ??? ??? ?if(temp==null) { //則已經遍歷完鏈表 ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ??? ?if(temp.number==newNode.number) { ?? ??? ??? ??? ?flag=true; ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ??? ?temp=temp.next; ?? ??? ?} ?? ??? ?if(flag) { ?? ??? ??? ?temp.name=newNode.name; ?? ??? ??? ?temp.nickName=newNode.nickName; ?? ??? ?}else { ?? ??? ??? ?System.out.printf("沒有找到編號為%d的節(jié)點",newNode.number); ?? ??? ?} ?? ?} ?? ?//展示鏈表 ?? ?public void show() { ?? ??? ?if(Head.next==null) { ?? ??? ??? ?System.out.println("鏈表為空!"); ?? ??? ??? ?return; ?? ??? ?} ?? ??? ?//因為頭節(jié)點不能動,所以通過輔助節(jié)點遍歷鏈表 ?? ??? ?Node temp=Head.next; ?? ??? ?while(true) { ?? ??? ??? ?//判斷是不是最后一個節(jié)點 ?? ??? ??? ?if(temp.next==null) { ?? ??? ??? ??? ?System.out.println(temp); ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ??? ?System.out.println(temp); ?? ??? ??? ?//temp指向下一個節(jié)點 ?? ??? ??? ?temp=temp.next; ?? ??? ?} ?? ?} } //創(chuàng)建節(jié)點 class Node{ ?? ?public int number; ?? ?public String name; ?? ?public String nickName; ?? ?public Node next; //指向下一個節(jié)點 ?? ?public Node pre;//指向前一個節(jié)點 ?? ?//構造器 ?? ?public Node(int number,String name,String nickName) { ?? ??? ?this.number=number; ?? ??? ?this.name=name; ?? ??? ?this.nickName=nickName; ?? ??? ? ?? ??? ? ?? ?} ?? ?@Override ?? ?public String toString() { ?? ??? ?return "Node [number=" + number + ", name=" + name + ", nickName=" + nickName + "]"; ?? ?} }
測試代碼:
public static void main(String[] args) { ?? ??? ?// TODO 自動生成的方法存根 ?? ??? ?Node node1=new Node(1,"宋江","及時雨"); ?? ??? ?Node node2=new Node(2,"盧俊義","玉麒麟"); ?? ??? ?Node node3=new Node(3,"吳用","智多星"); ?? ??? ?Node node4=new Node(4,"林沖","豹子頭"); ?? ??? ?Node node5=new Node(4,"linchong","豹子頭"); ?? ??? ?//創(chuàng)建一個鏈表 ?? ??? ?DoubleLinkedList linkedList=new DoubleLinkedList(); ?? ??? ?linkedList.AddNode2(node1); ?? ??? ?linkedList.AddNode2(node3); ?? ??? ?linkedList.AddNode2(node4); ?? ??? ?linkedList.AddNode2(node2); ?? ??? ?linkedList.show(); ?? ??? ? ?? ??? ?System.out.println("------------"); ?? ??? ?linkedList.remove(node4); ?? ??? ?linkedList.show(); ?? ?}
結果:
Node [number=1, name=宋江, nickName=及時雨]
Node [number=2, name=盧俊義, nickName=玉麒麟]
Node [number=3, name=吳用, nickName=智多星]
Node [number=4, name=林沖, nickName=豹子頭]
————————————————————————
Node [number=1, name=宋江, nickName=及時雨]
Node [number=2, name=盧俊義, nickName=玉麒麟]
Node [number=3, name=吳用, nickName=智多星]
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
java面試常見問題---ConcurrentHashMap
ConcurrentHashMap是由Segment數組結構和HashEntry數組結構組成。Segment的結構和HashMap類似,是一種數組和鏈表結構,今天給大家普及java面試常見問題---ConcurrentHashMap知識,一起看看吧2021-06-06Spring Cloud Gateway 攔截響應問題分析(數據截斷問題)
這篇文章主要介紹了Spring Cloud Gateway 攔截響應問題分析(數據截斷問題),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01Java Swing組件文件選擇器JFileChooser簡單用法示例
這篇文章主要介紹了Java Swing組件文件選擇器JFileChooser簡單用法,結合實例形式分析了Swing組件中的文件選擇器JFileChooser的簡單使用方法,需要的朋友可以參考下2017-11-11