大話數據結構(八)Java程序——雙向鏈表的實現


線性鏈表——雙向鏈表

雙向鏈表定義:

雙向鏈表(double linked list): 是在單表單的每個結點中,再設置一個指向前驅結點的指針域。因此,在雙向鏈表中的結點都有兩個指針域,一個指向前驅,一個指向后繼。

雙向鏈表的存儲結構

typedef struts DulNode{

Element data;

Struct DulNode *prior;前驅指針

Struct DulNode *next;后繼指針

}DulDouble, *DulLinkList;

雙向鏈表的插入與刪除

雙向鏈表的插入:

假設結點為s,要將結點插入到結點p和p->next中,我們需要下面幾步:

s.prev = p;

s.next = p.next;

p.next.prev = s;

p.next = s;

總結起來就是:先搞定s的前驅后繼,再搞定后結點的前驅,最后解決前驅結點的后繼

雙向鏈表的刪除:

要刪除p結點,只需要兩個步驟:

p.next.prev = p.prev;

p.prev.next = p.next;

free(p);

總結:

相對於單鏈表,雙向鏈表多了一個指針域,空間上要占用略多一點,但它有很好的對稱性,使得對某個結點的前后結點操作更容易,可以提高算法的時間性能,這是犧牲空間換取的。

Java程序實現雙鏈表:

package com.aclie.dataStructe4.sqeList;

public class MyDoubleLinkList {
    private int length =0;//當前長度
    private Node head;//頭結點
    private Node tail;//當前結點結點
 
    
    public MyDoubleLinkList(){
        initLink();
    }
    public void initLink(){
        head  = new Node(null);
        tail = new Node(null);
        this.head = tail;
        length++;
    }
    
    //獲取鏈表長度
    public int getSize(){
        return length;
    }
    //判斷鏈表是否為空
    public boolean getEmpty(){
        return getSize()==0;
    }
    //根據索引查找元素  從第一個有效值開始
    public Node getNode(int index){
        Node p;
        if(index < 0 || index > length ){
            System.out.println("參數錯誤");
        }
        if(index < this.length/2){
            p = this.head;
            for(int i=0; i<index; i++){
                p = p.next;
            }
        }else{
            p = this.tail;
            for(int i= length; i>index;i--){
                p = p.prev;
            }
        }
        return p;
    }
    
    public Object getData(int index){
        return getNode(index).data;
    }
    
    //在頭結點處插入
    public boolean addHead(Object e){
        //前驅引用為null,后繼為node
        Node node = new Node(e, null, this.head);
        //改變頭結點的前驅后繼
        this.head.prev = node;
        this.head = node;
        if(tail == null){
            tail =  this.head;
        }
        length++;
        return true;
    }
    //在尾結點插入
    public boolean addTail(Object e){
        if(this.head == null){
            this.head = new Node(e,null,null);
            this.tail = this.head;
        }else{
            Node node = new Node(e,this.tail,null);
            this.tail.next = node;
            this.tail = node;
            
        }
        length++;
        return true;
        
    }
    //在指定位置插入元素
    public boolean addData(int index,Object ele){
        if(index <0 || index > this.length){
            System.out.println("參數錯誤");
        }
        if(this.head == null){
            this.addTail(ele);//用尾插法
        }else{
            if(index == 0){
                addHead(ele);//用頭插法
            }else{
                Node p = this.getNode(index);//要插入處的結點
                Node n = p.next;
                Node node = new Node(ele,p,n);//要插入的結點
                n.prev = node;
                p.next = node;
                length ++;
                
            }
        }
        
        return true;
    }

    public void removeData(int index){
        if(index < 0 || index > length){
             System.out.println("參數錯誤");
         }else{
             Node del = null;
             if(index == 0){
                 del = this.head;
                 this.head = this.head.next;
                 this.head.prev = null;
                 length--;
             }else if(index == (length-1)){
                     Node p = this.getNode(index-1);//得到要刪除結點的前驅結點
                     del = p.next;//要刪除的結點
                     p.next = del.next;
                     if(del.next != null){
                         del.next.prev = p;
                     }
                     del.next = null;
                     del.prev = null;
                     length --;
                     
                     this.tail.next = null;
                     this.tail.prev = p;
                     this.tail = p;
                 }
             else{
                     Node p = this.getNode(index-1);//要刪除結點的前驅結點
                     del = p.next;//要刪除的結點
                     p.next = del.next;
                     if(del.next != null){
                         del.next.prev = p;
                     }
                     del.prev = null;
                     del.next = null;
                     length--;
                 }
             
         }
    }
    //打印所有鏈表中的元素
    public void print(){
        Node current = this.head;
        while(current != null){
            System.out.println(current.data);
            current = current.next;
        }
    }
    //反向打印鏈表
    public void reversePrint(){
        Node current = this.tail;
        while(current != null){
            System.out.println(current.data);
            current = current.prev;
        }
    }
    public static void main(String args[]){
        MyDoubleLinkList linkList = new MyDoubleLinkList();
        linkList.addHead("aaaa");
//        System.out.println(linkList.getData(1));
        linkList.addTail("bbbb");
//        System.out.println(linkList.getData(3));
        linkList.addData(2, "eeee");
//        linkList.print();
        linkList.removeData(2);
        linkList.print();
        System.out.println(".....");
        linkList.reversePrint();
    }
    
}
class Node{
    Node prev;//指針域中前驅
    Node next;//指針域中后繼
    Object data;//數據域
    public Node(Node current){
        prev = current;
        next = current;
    }
    //雙鏈表前驅后繼及數字域
    public Node(Object d, Node p,Node n){
        this.data = d;
        this.prev = p;
        this.next = n;
    }
    public Node getPrev() {
        return prev;
    }
    public void setPrev(Node prev) {
        this.prev = prev;
    }
    public Node getNext() {
        return next;
    }
    public void setNext(Node next) {
        this.next = next;
    }
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM