雙向鏈表,每個節點除了保存了對下一個節點的引用,同時還保存這對前一個節點的引用。
其結點跟單鏈表相似,如圖所示:
設計雙向鏈表的操作:
1、結點數據:
/**
* 鏈表節點,相當於火車的車廂
* @author Administrator
*
*/
public class MyNode {
//數據域
public long data;
//指針域
public MyNode next;
/**
* 前指針域
*/
public MyNode previous;
/**
* 創建節點,數據域賦值
* @param value
*/
public MyNode(long value){
this.data=value;
}
public void display(){
System.err.print(data+" ");
}
}
雙向鏈表類:
/**
* 雙向鏈表,每個節點除了保存了對下一個節點的引用,同時還保存這對前一個節點的引用
* @author Administrator
*
*/
public class MyDoubleLink {
/**
* 頭結點
*/
private MyNode first;
private MyNode last;
/**
* 構造方法
*/
public MyDoubleLink(){
first=null;
last=null;
}
}
2、在尾部追加結點:
/**
* 插入結點,從尾結點插入,
* @param value
*/
public void insertLast(long value){
MyNode node=new MyNode(value);
if (isEmpty()) {
first=node;//若鏈表爲空,則設置頭結點爲新增節點
}else {
last.next=node;//若鏈表不爲空,則設置尾結點的下一個節點爲新增結點,同時設置新增加的節點的前指針指向爲尾結點
node.previous=last;
}
last=node;
}
3、在頭部插入節點:
/**
* 在頭結點後插入節點,如果爲空,則設置新增節點爲尾結點,如果不爲空,還需要設置頭結點的前一個節點爲新增結點
* @param value
*/
public void insetFirst(long value){
MyNode node=new MyNode(value);
if (isEmpty()) {
last=node;
}else{
first.previous=node;
}
node.next=first;
first=node;
}
4、根據關鍵字查詢結點:
/**
* 查找方法
* @param value
* @return
*/
public MyNode find(long value){
MyNode currNode=first;
while(currNode!=null){
if (currNode.data==value) {
return currNode;
}
currNode=currNode.next;
}
return null;
}
5、在結點中間的某一個位置插入節點:
/**
* 在關鍵字之後插入結點
* @param value
* @param key
*/
public void insertFindByKey(long value,long key){
MyNode curNode=find(key);
if (curNode==null) {
System.out.println("未找到插入結點的位置");
}else {
MyNode node=new MyNode(value);//要插入的結點
node.previous=curNode;
node.next=curNode.next;
node.previous.next=node;
node.next.previous=node;
}
}
6、刪除結點
(1)、刪除頭結點後的節點,從頭部開始刪除
/**
* 刪除頭結點後的節點,從頭部開始刪除
* @return
*/
public MyNode deleteFirst(){
MyNode temp=first;//頭結點
if (first.next==null) {
last=null;
}else {
first.next.previous=null;
}
first=temp.next;
return temp;
}
(2)、刪除結點,從尾結點刪除
/**
* 刪除結點,從尾結點刪除
* 如果頭結點後沒有其他結點,則設置頭結點爲null。
* 否則設置尾結點的前一個結點的next爲null。
* 設置尾結點爲其前一個結點。
* @return
*/
public MyNode deleteLast(){
MyNode temp=last;
if (first.next==null) {
first=null;
}else {
last.previous.next=null;
}
last=last.previous;//將last的前一個節點設置爲尾結點。
return temp;
}
(3)、根據關鍵字刪除結點
/**
* 刪除
* @param value
* @return
*/
public MyNode delete(long value){
MyNode currNode=first;
while(currNode.data!=value){
if (currNode.next==null) {
return null;
}
currNode=currNode.next;
}
if (currNode==first) {
first=first.next;
}else {
currNode.previous.next=currNode.next;
}
return currNode;
}
7、顯示所有結點:
/**
* 顯示結點
*/
public void display(){
MyNode currNode=first;
while(currNode!=null){
currNode.display();
currNode=currNode.next;
}
}
8、判斷鏈表是否爲空
/**
* 判斷是否爲空
* @return
*/
public boolean isEmpty(){
return first==null;
}