教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

java數(shù)據(jù)結構-雙鏈表的數(shù)據(jù)操作及特性

更新時間:2018年12月07日11時35分 來源:傳智播客 瀏覽次數(shù):

# 數(shù)據(jù)結構-雙鏈表的數(shù)據(jù)操作及特性

java

## 概述

? 上一章中,我們已經(jīng)入門了單鏈表的添加數(shù)據(jù),刪除數(shù)據(jù)及更新數(shù)據(jù),但是在刪除的時候,或者在更新的時候,它的效率不高因為,沒一個節(jié)點只記錄了它的下一個節(jié)點,這樣一來,遍歷節(jié)點就變得很慢,添加時,添加到指定的節(jié)點就變得效率低下。那么怎么解決呢?這一章,我們來看看雙鏈表是如何操作的,以及如何遍歷和快速的添加節(jié)點的。

## 雙鏈表介紹

? 雙向鏈表也叫[雙鏈表](https://baike.baidu.com/item/%E5%8F%8C%E9%93%BE%E8%A1%A8),是鏈表的一種,它的每個數(shù)據(jù)結點中都有兩個[指針](https://baike.baidu.com/item/%E6%8C%87%E9%92%88),分別指向直接后繼和直接前驅(qū)。所以,從雙向鏈表中的任意一個結點開始,都可以很方便地訪問它的前驅(qū)結點和后繼結點。

![](image\image1.png)

## 定義節(jié)點及鏈表對象

```java

/**

* 雙鏈表

* @title DoubleLink.java

*

description

*

company: www.itheima.com

* @author 三國的包子

* @version 1.0

*

*/

public class DoubleLink {

//節(jié)點對象

private class Node{

Node prev;//記錄當前節(jié)點的上一個節(jié)點的內(nèi)存地址

Node next;//記錄當前節(jié)點的下一個節(jié)點的內(nèi)存地址

Object data;//當前節(jié)點的數(shù)據(jù)

}

private Node head;//頭節(jié)點

private Node rear;//尾節(jié)點

}

```

#### 從尾部添加節(jié)點到鏈表

##### 分析

從尾部添加節(jié)點,首先在鏈表中,有一個head 指向頭節(jié)點 有一個rear指向尾部節(jié)點,并且如果只有一個節(jié)點,這個節(jié)點既是頭節(jié)點也是尾節(jié)點,如果有多個節(jié)點,那么根據(jù)節(jié)點的增加,尾部節(jié)點(rear)指向的節(jié)點不同。

添加的過程:

? 1.創(chuàng)建數(shù)據(jù)節(jié)點

? 2.將數(shù)據(jù)放入節(jié)點中

? 3.判斷尾部節(jié)點是否為空,如果為空,說明鏈表還是空的,此時 新增節(jié)點即為頭節(jié)點和尾節(jié)點

? 4.如果尾部節(jié)點不為空,鏈表存在,需要將新增的節(jié)點加入到列表中(即原尾部節(jié)點的后面),并移動rear 執(zhí)行新增的節(jié)點。

##### 編寫添加的代碼

```java

/**

* 從尾部添加節(jié)點

* @param data

*/

public void addFromRear(Object data){

// 1. 創(chuàng)建新的節(jié)點

Node node = new Node();

// 2. 把數(shù)據(jù)放入節(jié)點中

node.data = data;

// 3. 判斷尾部節(jié)點是否為空 如果為空說明鏈表還是空的

if (rear == null) {

rear = node;

head = node;

} else {

// 4. 判斷如果尾部節(jié)點不為空,說明 鏈表是存在的

//將新增的節(jié)點的內(nèi)存地址賦給 原尾節(jié)點的的next 屬性

rear.next = node;

//將原尾節(jié)點的地址 賦給 新增節(jié)點的 prev 屬性

node.prev = rear;

//最后 將新增的節(jié)點 賦給尾節(jié)點引用

rear = node;

}

}

```

##### 代碼實現(xiàn)的過程如下

![](image\image2.png)

## 重寫toString

### 分析

? 添加完成節(jié)點之后,需要遍歷節(jié)點打印 查看鏈表的內(nèi)容。所以這里我們重寫toString方法。

重寫toString ,需要在鏈表中從頭節(jié)點開始遍歷,遍歷到尾部節(jié)點之后將每一個節(jié)點的數(shù)據(jù)連接起來。這里我們實現(xiàn)一個字符串連接。

### 實現(xiàn)

?

```java

//[a,b,c]

@Override

public String toString() {

StringBuilder sbBuilder = new StringBuilder("[");

// 遍歷鏈表中所有的數(shù)據(jù)

Node node = head;// 從頭節(jié)點開始遍歷數(shù)據(jù)

while (node != null) {

//如果node還沒遍歷到尾部節(jié)點

if (node != rear) {

//就有逗號

sbBuilder.append(node.data + ", ");

} else {

sbBuilder.append(node.data);

}

// 條件的改變:將下一個節(jié)點賦值給當前node 引用。直到node.next=null 說明已經(jīng)到尾部節(jié)點

node = node.next;

}

sbBuilder.append("]");

return sbBuilder.toString();

}

```

## 測試

```java

package com.itheima.link;

public class TestDoubleLink {

public static void main(String[] args) {

DoubleLink doubleLink = new DoubleLink();

doubleLink.addFromRear("abc1");

doubleLink.addFromRear("abc2");

doubleLink.addFromRear("abc3");

System.out.println(doubleLink);

}

}

```

測試效果:

```java

[abc1, abc2, abc3]

```

## 總結

? 通過添加節(jié)點,我們發(fā)現(xiàn),雙向鏈表是 有一個前驅(qū) 和 后繼節(jié)點指針。這樣就可以從任意的節(jié)點處添加節(jié)點了。只需要改變prev next 即可。下一章節(jié),我們來討論如何從中間位置添加節(jié)點以及從頭部添加節(jié)點。這樣大家就可以很好對比單鏈表了。今天先入門到這里。

0 分享到:
和我們在線交談!