亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

數據結構Java實現:循環鏈表和雙向鏈表

 

上篇教程給大家分享了單鏈表的概念,以及如何用 JAVA 實現一個單鏈表的結構。單鏈表是最基礎的一種鏈表結構,在實際開發中的使用有一些局限性,比如只能單向往后查找節點,如果需要找到某元素的前驅節點,單鏈表是無法實現的,今天來給大家分享另外兩個復雜一些的鏈表結構:循環鏈表和雙向鏈表。

循環鏈表

循環鏈表本質上就是一種單鏈表,兩者的不同之處在于鏈表中最后一個節點的指針指向哪里,在單鏈表中,末尾節點的指針指向空,如下圖所示。

 

數據結構Java實現:循環鏈表和雙向鏈表

 

第一個元素 a 的指針指向 1008,即第二個元素 b 的首地址,b 的指針指向第三個元素 c 的內存地址 1020,沒有第四個元素,所以 c 的指針指向空。

而在循環鏈表中,末尾節點的指針指向首節點,形成一個閉環,所以它叫循環鏈表,應該很好理解,如下圖所示。

數據結構Java實現:循環鏈表和雙向鏈表

 

接下來用 Java 實現一個循環鏈表的結構,只需要在原有單鏈表的基礎上稍作修改即可,如下所示。

package com.southwind.link;
public class Node {
 //數據
 public Object data;
 //下一個節點
 public Node next;
 public Node(Object data){
 this.data = data;
 }
}
package com.southwind.link;
public class LoopLinkedList {
 public int size;
 public Node head;
 /**
 * 添加元素
 * @param obj
 * @return
 */
 public Node add(Object obj){
 Node newNode = new Node(obj);
 if(size == 0){
 head = newNode;
 head.next = head;
 }else{
 Node target = head;
 while(target.next!=head){
 target = target.next;
 }
 target.next = newNode;
 newNode.next = head;
 }
 size++;
 return newNode;
 }
 /**
 * 在指定位置插入元素
 * @return
 */
 public Node insert(int index,Object obj){
 if(index >= size){
 return null;
 }
 Node newNode = new Node(obj);
 if(index == 0){
 newNode.next = head;
 head = newNode;
 }else{
 Node target = head;
 Node previous = head;
 int pos = 0;
 while(pos != index){
 previous = target;
 target = target.next;
 pos++;
 }
 previous.next = newNode;
 newNode.next = target;
 }
 size++;
 return newNode;
 }
 /**
 * 刪除鏈表頭部元素
 * @return
 */
 public Node removeHead(){
 if(size > 0){
 Node node = head;
 Node target = head;
 while(target.next!=head){
 target = target.next;
 }
 head = head.next;
 target.next = head;
 size--;
 return node;
 }else{
 return null;
 }
 }
 /**
 * 刪除指定位置元素
 * @return
 */
 public Node remove(int index){
 if(index >= size){
 return null;
 }
 Node result = head;
 if(index == 0){
 head = head.next;
 }else{
 Node target = head;
 Node previous = head;
 int pos = 0;
 while(pos != index){
 previous = target;
 target = target.next;
 pos++;
 }
 previous.next = target.next;
 result = target;
 }
 size--;
 return result;
 }
 /**
 * 刪除指定元素
 * @return
 */
 public Node removeNode(Object obj){
 Node target = head;
 Node previoust = head;
 if(obj.equals(target.data)){
 head = head.next;
 size--;
 }else{
 while(target.next!=null){
 if(obj.equals(target.next.data)){
 previoust = target;
 target = target.next;
 size--;
 break;
 }else{
 target = target.next;
 previoust = previoust.next;
 }
 }
 previoust.next = target.next;
 }
 return target;
 }
 /**
 * 返回指定元素
 * @return
 */
 public Node findNode(Object obj){
 Node target = head;
 while(target.next!=null){
 if(obj.equals(target.data)){
 return target;
 }else{
 target = target.next;
 }
 }
 return null;
 }
 /**
 * 輸出鏈表元素
 */
 public void show(){
 if(size > 0){
 Node node = head;
 int length = size;
 System.out.print("[");
 while(length > 0){
 if(length == 1){
 System.out.print(node.data);
 }else{
 System.out.print(node.data+",");
 }
 node = node.next;
 length--;
 }
 System.out.println("]");
 }else{
 System.out.println("[]");
 }
 }
}

雙向鏈表

雙向鏈表是相對單鏈表來講的,區別在于單鏈表中只有一個指針指向下一個節點,是單向連接的,只能從當前節點訪問它的后繼節點。而雙向鏈表顧名思義是雙向連接的,既可以從當前節點訪問到后繼節點,也可以訪問到前驅節點,所以在雙向鏈表中有兩個指針,一個叫做后繼指針,指向下一個節點,另一個叫做前驅指針,指向它的上一個節點,雙向鏈表的結構如下圖所示。

數據結構Java實現:循環鏈表和雙向鏈表

 

雙向鏈表相比于單鏈表會占用更多的內存空間,因為多了一個指針來存儲前驅節點的內存地址。雖然如此,但是在某些操作上,相比于單鏈表,雙向鏈表可以極大地提升效率。

比如要刪除鏈表中的某個節點,那么我們就需要獲取到目標節點的前驅節點,然后將前驅節點的指針指向目標節點的下一個節點,如下圖所示。

數據結構Java實現:循環鏈表和雙向鏈表

 

如上所示,刪除節點必須先找到其前驅節點,在單鏈表中是不會記錄元素的前驅節點的,所以必須從頭開始遍歷鏈表,直到找到目標節點的前驅節點,時間復雜度為 O(n)。

如果是雙向鏈表的結構,每一個節點都會記錄其前驅節點,可直接獲取,所以此時的時間復雜度為 O(1)。

數據結構Java實現:循環鏈表和雙向鏈表

 

搞清楚了雙向鏈表的概念,接下來我們用 Java 來實現雙向鏈表的結構。

 

package com.southwind.link;
public class DoubleNode {
 //數據
 public Object data;
 //下一個節點
 public DoubleNode next;
 //上一個節點
 public DoubleNode previous;
 public DoubleNode(Object data){
 this.data = data;
 }
}
package com.southwind.link;
public class DoubleLinkedList {
 public int size;
 public DoubleNode head;
 /**
 * 添加元素
 * @param obj
 * @return
 */
 public DoubleNode add(Object obj){
 DoubleNode newNode = new DoubleNode(obj);
 if(size == 0){
 head = newNode;
 }else{
 DoubleNode target = head;
 while(target.next!=null){
 target = target.next;
 }
 target.next = newNode;
 newNode.previous = target;
 }
 size++;
 return newNode;
 }
 /**
 * 在指定位置插入元素
 * @return
 */
 public DoubleNode insert(int index,Object obj){
 if(index >= size){
 return null;
 }
 DoubleNode newNode = new DoubleNode(obj);
 if(index == 0){
 newNode.next = head;
 head.previous = newNode;
 head = newNode;
 }else{
 DoubleNode target = head;
 int pos = 0;
 while(pos != index){
 target = target.next;
 pos++;
 }
 newNode.previous = target.previous;
 newNode.previous.next = newNode;
 newNode.next = target;
 }
 size++;
 return newNode;
 }
 /**
 * 刪除鏈表頭部元素
 * @return
 */
 public DoubleNode removeHead(){
 if(size > 0){
 DoubleNode node = head;
 head = head.next;
 size--;
 return node;
 }else{
 return null;
 }
 }
 /**
 * 刪除指定位置元素
 * @return
 */
 public DoubleNode remove(int index){
 if(index >= size){
 return null;
 }
 DoubleNode result = head;
 if(index == 0){
 DoubleNode node = head;
 head = head.next;
 }else{
 DoubleNode target = head;
 int pos = 0;
 while(pos != index){
 target = target.next;
 pos++;
 }
 target.previous.next = target.next;
 }
 size--;
 return result;
 }
 /**
 * 刪除指定元素
 * @return
 */
 public DoubleNode removeNode(Object obj){
 DoubleNode target = head;
 if(obj.equals(target.data)){
 DoubleNode node = head;
 head = head.next;
 size--;
 }else{
 while(target.next!=null){
 if(obj.equals(target.data)){
 target.previous.next = target.next;
 size--;
 break;
 }
 target = target.next;
 }
 }
 return target;
 }
 /**
 * 返回指定元素
 * @return
 */
 public DoubleNode findNode(Object obj){
 DoubleNode target = head;
 while(target.next!=null){
 if(obj.equals(target.data)){
 return target;
 }else{
 target = target.next;
 }
 }
 if(target.next==null && obj.equals(target.data)){
 return target;
 }
 return null;
 }
 /**
 * 輸出鏈表元素
 */
 public void show(){
 if(size > 0){
 DoubleNode node = head;
 int length = size;
 System.out.print("[");
 while(length > 0){
 if(length == 1){
 System.out.print(node.data);
 }else{
 System.out.print(node.data+",");
 }
 node = node.next;
 length--;
 }
 System.out.println("]");
 }else{
 System.out.println("[]");
 }
 }
}

分享到:
標簽:數據結構
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定