- 今天就是五一了。有女朋友得都出去浪去了。然而像我這單身屌絲。只能在家擼代碼。真是代碼虐我千百遍,我對代碼如初戀。一天就是10個小時的學習開始了。
- 今天我們學習雙向鏈表用java實現。因爲以前學習數據結構的沒用功,以至於現在學了一早上也僅僅理解了一些。
- 什麼是雙向鏈表呢?
- 每一個結點除了保存對下一個結點的的引用,同時還保存對前一個結點的引用
- 從頭部進行插入
- 要對鏈表進行判斷
- 要對鏈表進行判斷,如果爲空的話就設置尾結點爲新添加的結點,如果不爲空,還需要設置頭結點的前一個結點爲新添加的結點。
- 從尾部插入
- 如果鏈表爲空,直接設置頭結點爲新添加的結點。否則設置尾結點的後一個結點爲添加的結點。同時設置添加的結點的前一個的引用
數據結構如下圖:
廢話不多說話了直接上代碼
先創建一個結點類
/**
* 雙向鏈表需要的節點
* @author Administrator
*
*/
public class Link {
public long data;
//指針域
public Link next;
//指針域
public Link provious;
public Link(long dd){
data = dd;
}
public void display(){
System.out.print(data+" ");
}
}
在創建雙向鏈表的實現
public class DoublyLink {
//頭節點
private Link first;
//尾節點
private Link last;
public DoublyLink(){
first = null;
last = null;
}
/**
* 從頭節點開始添加
* @param d
*/
public void insertFirst(long d){
Link newlink = new Link(d);
if(isEmpty()){
last = newlink;//如果爲空話。last = 新添加的節點
}else{
first.provious = newlink;//第一個的前一指針指向先節點
}
newlink.next =first;//新節點的next指向 原來的第一個
first =newlink;//第一個變成新的
}
public void insertLast(long d){
Link newlink = new Link(d);
if(isEmpty()){
first = newlink;
}else{
last.next=newlink;
newlink.provious=last;
}
last = newlink;
}
public Link deleteFirst(){
Link temp = first;
if(first.next == null){
last = null;
}else{
first.next.provious =null;
}
first = first.next;
return temp;
}
public Link deleteLast(){
Link temp = last;
if(last.provious ==null){
first = null;
}else{
//清楚前一個的引用
last.provious.next=null;
}
last =last.provious;
return temp;
}
public boolean insertAfter(long key,long data){
Link newLink = new Link(data);
Link current =first;
while(current.data !=key){
current= current.next;
if(current ==null){
return false;
}
}
if(current == last){
newLink.next=null;
last = newLink;
}else{
//設置newLink 的前後的指針
newLink.next =current.next;
current.next.provious =newLink;//設置要添加的節點的下一個的前一個的指針域
}
newLink.provious = current;
current.next= newLink;
return true;
}
public Link deletekey(long key){
Link current = first;
while(current.data != key){
current = current.next;
if(current == null){
return null;
}
}
//1,先處理next 的引用
if(current == first){
//刪除第一個節點。
first =first.next;
}else{
//如果不是第一個就刪除前一個節點的next 引用
current.provious.next = current.next;
}
// 在處理provious 的引用
if(current == last){//如果是最後一個的話,就刪除最後一個
last =current.provious;
}else{
//[1][2][3] 當前的下一個的provious 指向要刪除的這個節點的prov
current.next.provious = current.provious;
}
return current;
}
public void displayForward(){
System.out.print("first--->last:");
Link current = first;
while(current!=null){
current.display();
current = current.next;
}
System.out.println();
}
public void displayBackward(){
System.out.print("last--->first:");
Link current = last;
while(current!=null){
current.display();
current = current.provious;
}
System.out.println();
}
public boolean isEmpty(){
return first == null;
}
}
在創建測試類:
public static void main(String[] args) {
DoublyLink d = new DoublyLink();
d.insertFirst(20);
d.insertFirst(40);
d.insertFirst(60);
d.insertLast(11);
d.insertLast(33);
d.insertLast(55);
d.displayForward();
d.displayBackward();
d.deleteFirst();
d.deleteLast();
d.displayForward();
d.deletekey(11);
d.displayForward();
d.insertAfter(20, 25);
d.insertAfter(33, 77);
d.displayForward();
d.deletekey(40);
d.displayForward();
}
測試結果如下:
first--->last:60 40 20 11 33 55
last--->first:55 33 11 20 40 60
first--->last:40 20 11 33
first--->last:40 20 33
first--->last:40 20 25 33 77
first--->last:20 25 33 77
對雙向鏈表學的不好的同學。寫起來可能比較費勁。我也是一邊畫圖,一邊理解。現在記下來以便以後加強記憶。