java資料結構——雙向連結串列
阿新 • • 發佈:2018-11-11
連結串列是非常常見的一類線性結構的資料結構,每個節點包含有指標域和資料域,常見的包括單項列表、雙向列表、迴圈列表。這篇文章將詳細介紹雙向連結串列。
雙端連結串列不同於單向連結串列僅有一個指標域指向下一個節點,而是同時持有下一個和上一個指標域,分別指向下一個和上一個節點,如下:
本文將介紹雙向連結串列的插入節點、根據位置插入節點、刪除頭結點、刪除尾節點、刪除指定位置節點,檢視連結串列元素、檢視頭結點、檢視尾節點、檢視連結串列長度、判斷連結串列是否為空。
連結串列的節點表示:
class Node { //資料域 public String data; //上一個節點 public Node prev; //下一個節點 public Node next; public Node(String data) { this.data = data; } }
在建立好連結串列節點之後下來看連結串列的構造方法和成員變數,成員方法包括一個完整連結串列的頭結點、尾節點以及連結串列的長度:
class DoubleLinkedList {
private Node tailNode;
private Node headNode;
private int length;
public DoubleLinkedList() {
tailNode = null;
headNode = null;
}
}
1、插入元素:尾部插入
/** * 插入元素 */ public void insert(String value) { if (value == null || value.isEmpty()) { throw new NullPointerException(); } Node node = new Node(value); if (headNode == null) { headNode = node; tailNode = headNode; tailNode.prev = null; tailNode.next = null; } else { tailNode.next = node; node.prev = tailNode; tailNode = node; } length++; }
2、插入元素:指定位置
/** * 根據位置插入節點 */ public void insert(int position, String value) { //建立要插入的節點 Node node = new Node(value); if (position >= length) { //直接插入到尾部 insert(value); return; } if (position == 0) { Node firstNode = headNode; headNode = node; headNode.prev = null; headNode.next = firstNode; firstNode.prev = node; } else { //獲取到該位置的節點 Node nodeByPosition = getNodeByPosition(position); //上一個節點 Node prevNode = nodeByPosition.prev; //下一個節點 Node nextNode = nodeByPosition.next; //上一個節點next指向他 prevNode.next = node; //他的上一個節點指向prev node.prev = prevNode; //他的下一個節點指向next node.next = nodeByPosition; //下一個節點的pre指向他 nodeByPosition.prev = node; } length++; }
3、刪除元素:刪除頭部
/**
* 刪除連結串列頭部
*/
public Node deleteHead() {
//獲取根節點的下一個節點
Node nextNode = null;
Node firstNode = null;
if (headNode != null) {
nextNode = headNode.next;
} else {
return null;
}
if (nextNode == null) {
headNode = null;
} else {
firstNode = headNode;
nextNode.prev = null;
headNode.next = null;
headNode = nextNode;
}
length--;
return firstNode;
}
4、刪除元素:刪除尾部
/**
* 刪除連結串列尾部
*/
public Node deleteTail() {
//獲取根節點的下一個節點
Node preNode = null;
Node lastNode = null;
if (tailNode != null) {
preNode = tailNode.prev;
} else {
return null;
}
if (preNode == null) {
headNode = tailNode;
} else {
lastNode = tailNode;
tailNode.prev = null;
preNode.next = null;
tailNode = preNode;
}
length--;
return lastNode;
}
5、刪除元素:刪除指定位置
/**
* 刪除指定位置節點
*/
public Node deleteByPosition(int position) {
if (position >= length) {
throw new IllegalArgumentException(" position must be less than linklist all length ");
} else {
Node nodeByPosition = getNodeByPosition(position);
if (position == 0) {
//刪除頭結點
Node deleteHead = deleteHead();
return deleteHead;
} else if (position == length - 1) {
//刪除尾節點
Node deleteTail = deleteTail();
return deleteTail;
} else {
//有頭有尾
//獲取該節點的前一個和後一個節點
Node prevNode = nodeByPosition.prev;
Node nextNode = nodeByPosition.next;
prevNode.next = nextNode;
nextNode.prev = prevNode;
length--;
return nodeByPosition;
}
}
}
6、根據位置獲取節點
/**
* 根據位置獲取節點
*/
public Node getNodeByPosition(int position) {
Node current = headNode;
if (position >= length) {
throw new IllegalArgumentException(" position must be less than linklist all length ");
} else {
for (int i = 0; i < length; i++) {
if (i == position) {
break;
}
if (current != null) {
current = current.next;
}
}
}
return current;
}
7、檢視所有節點
/**
* 列印所有節點
*/
public void displayAll() {
Node current = headNode;
while (current != null) {
System.out.print(current.data + " ");
current = current.next;
}
}
8、檢視頭結點
/**
* 檢視頭結點
*/
public Node getheadNode() {
return headNode;
}
9、檢視尾節點
/**
* 檢視當尾節點
*/
public Node getTailNode() {
return tailNode;
}
10、獲取連結串列長度
/**
* 連結串列長度
*/
public int length() {
return length;
}
11、判斷連結串列是否為空
/**
* 判斷連結串列是否為空
*/
public boolean isEmpty() {
return length == 0;
}