在前面我们介绍了使用Node数据结构实行单链表,那么这篇博客我们来介绍一下如何实现双向链表。双向链表其实结构上和单链表非常相似,唯一的不同是构成双向链表的Node中比单链表的Node多一个preNode数据域,preNode指向前一个Node。
- 双向链表与单链表在特性上的比较:
- 单向链表,查找的方向只能是一个方向,而双向链 表可以向前或者向后查找。
- 单向链表不能自我删除,需要靠辅助节点 ;而双向链表,则可以自我删除 。该特性使得双向链表节点的删除更加容易。
- 在实现双向链表之前我们规定:
- 头结点不存储数据。
- 第一个数据节点向前指向null,最后一个节点向后指向null。
- 代码实现:
public class bidiretionalLinkList {
class Node{
private int data;
private Node preNode;
private Node postNode;
public Node(int data){
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getPreNode() {
return preNode;
}
public void setPreNode(Node preNode) {
this.preNode = preNode;
}
public Node getPostNode() {
return postNode;
}
public void setPostNode(Node postNode) {
this.postNode = postNode;
}
}
private int size;
private Node headNode;
public bidiretionalLinkList(){
this.size = 0;
this.headNode = new Node(0);
}
/**
* new a node according to the data, and append it at end of linklist
* @param data
*/
public void appendNode(int data){
Node temp = this.headNode;
//find the last node.
while (temp.postNode != null){
temp = temp.postNode;
}
Node node = new Node(data);
if(temp == this.headNode){
node.setPreNode(null);
}else {
node.setPreNode(temp);
}
temp.setPostNode(node);
++ this.size;
}
/**
* delete a node according to given data
* @param data
*/
public void deleteNodeByData(int data){
if(this.headNode.getPostNode() == null)
return;
Node temp = this.headNode.getPostNode();
while (temp.getData() != data){
temp = temp.getPostNode();
}
//如果该节点是第一个节点,需要把该节点前前指向null
if(temp.getPreNode() == this.headNode){
this.headNode.setPostNode(null);
}else {
temp.getPreNode().setPostNode(temp.getPostNode());
temp.getPostNode().setPreNode(temp.getPreNode());
temp = null;
}
--this.size;
}
/**
* delete a node according to the index
* @param index
* @return, the deleted node.
*/
public Node deleteNodeByIndex(int index){
if(this.size == 0 || index > this.size || index <= 0){
return null;
}
Node temp = this.headNode;
for(int i = 0;i < index;i ++){
temp = temp.getPostNode();
}
if(temp.getPreNode() == this.headNode){
this.headNode.setPostNode(null);
}else {
temp.getPreNode().setPostNode(temp.getPostNode());
temp.getPostNode().setPreNode(temp.getPreNode());
}
--this.size;
return temp;
}
/**
* update node's data according to the node index.
* @param index
* @param data
* @return, the original data
*/
public int updateNode(int index, int data){
if(this.size == 0 || index > this.size || index <= 0){
return Integer.MIN_VALUE;
}
Node temp = this.headNode;
for(int i = 0;i < index;i ++){
temp = temp.getPostNode();
}
int tempData = temp.getData();
temp.setData(data);
return tempData;
}
}
/**
* print all nodes in the linklist
*/
public void printAllNode(){
Node temp = this.headNode;
while (temp.getPostNode() != null){
System.out.println(temp);
temp = temp.getPostNode();
}
}