用Java實現鏈表結構對象:單向無環鏈表


 

轉載請注明本文出處:http://www.cnblogs.com/Starshot/p/6918569.html

 

鏈表的結構是由一個一個節點組成的,所謂鏈,就是每個節點的頭尾連在一起。而單向鏈表就是:每個節點包含了當前節點的值和下一個節點引用。雙向鏈表就是每個節點包含了當前節點的值和上下兩個節點的引用。相對於數組結構,鏈表的增刪效率會更加高。

這邊文章主要講怎么用Java實現一個簡單的鏈表結構:單向無環鏈表。以及實現一些數據處理的方法。

 

首先,新建一個節點類(本次例子中的節點值都是字符串類型):

 1 public class Node {
 2 
 3     private String value;
 4     private Node next;
 5     
 6     public Node(String value){
 7         this.value=value;
 8     }
 9     public Node(){
10         
11     }
12     
13     public String getValue(){
14         return value;
15     }
16     
17     public Node getnext(){
18         return next;
19     }
20     
21     public void setValue(String value){
22         this.value=value;
23     }
24     
25     public void setNext(Node next){
26         this.next=next;
27     }
28 }

 

然后再建一個鏈表類:

public class MyLinkedTable {

    Node head=new Node();
    
    //向鏈表中增加值
    public boolean add(String str){
        Node node=new Node(str);
        if(head.getnext()==null){
            head.setNext(node);;
            return true;
        }
        
        Node tmp=head;
        
        while(tmp.getnext()!=null){
            tmp=tmp.getnext();
        }
        
        tmp.setNext(node);
        
        return true;
        
    }
    //已知某個節點,然后刪除該節點
    public boolean delete(Node node){
        Node next=node.getnext();
        Node nextAddress=next.getnext();
        String nextValue=next.getValue();
        node.setNext(nextAddress);
        node.setValue(nextValue);
        return true;
    }
    
       //刪除第index個節點,index從1開始
    public boolean delete(int index){
        
        if(index>length()||index<1){
            return false;
        }
        
        int i=1;
        Node temp=head.getnext();
        while(i<index){
            temp=temp.getnext();
            i++;
        }
        
        Node next=temp.getnext();
        Node nextAddress=next.getnext();
        String nextValue=next.getValue();
        temp.setNext(nextAddress);
        temp.setValue(nextValue);
        
        return true;
    }
    
        //獲得第index個節點的值
    public String get(int index){
        if(index>length()||index<1){
            return null;
        }
        
        int i=1;
        Node temp=head.getnext();
        while(i<index){
            temp=temp.getnext();
            i++;
        }
        
        return temp.getValue();
    }
    
       //獲取鏈表里面數據的長度,也就是插入了多少個值。
    public int length(){
        
        if(head.getnext()==null){
            return 0;
        }
        
        int i=1;
        Node temp=head.getnext();
        while((temp=temp.getnext())!=null){
            i++;
        }
        
        return i;
    }
    
    //反轉鏈表
    public void reverseTable(){
        Node node1=head.getnext();
        
        if(node1==null){
            return;
        }
        
        Node preNode=null;
        Node curNode=node1;
        
        while(true){
            Node origNextNode=curNode.getnext();
            curNode.setNext(preNode);
            if(origNextNode==null){
                head.setNext(curNode);
                break;
            }
            preNode=curNode;
            curNode=origNextNode;
        }
        
    }
    
    //獲取中間鏈表
    public String getMid(){
        
        Node slowPointer=this.head.getnext(),fastPointer=this.head.getnext();
        while(fastPointer!=null&&fastPointer.getnext()!=null&&fastPointer.getnext().getnext()!=null){
            slowPointer=slowPointer.getnext();
            fastPointer=fastPointer.getnext().getnext();
        }
        
        return slowPointer.getValue();
        
    }
    
       //刪除重復鏈表
    public void deleteDuplicateNode(){
        Node nodeCur=head.getnext();
        
        if(nodeCur==null) return;
        
        while(nodeCur.getnext()!=null){
            Node lastNode=nodeCur;
            Node compareNode=lastNode.getnext();
            while(compareNode!=null){
                
                if(nodeCur.getValue().equals(compareNode.getValue())){
                    lastNode.setNext(compareNode.getnext());
                    compareNode=compareNode.getnext();
                }else{
                    
                    lastNode=compareNode;
                    compareNode=compareNode.getnext();
                }
            }
            nodeCur=nodeCur.getnext();
        }
    }
}

 

需要說明一下,這個鏈表結構是以head為起始節點,head指向插入的第一個節點(反轉后就是最后一個),head本身的value一直都是空的,它只作為起始節點入口存在,不參與節點的計數,所以鏈表的節點總數(插入數據總數)是不包括head在內的。

接下來對某些方法進行說明:

1.鏈表反轉

//鏈表翻轉就是把原來的1>2>3>4變成4>3>2>1,所以原來在最前面的節點要變成在最后面,最后面的要變成最前面
    //就是head的地址引用要變成最后一個節點的,原來head后的第一個節點的地址引用要由第二的節點變為NULL,原來第二個節點的地址引用要由第三個節點變成第一個節點
    //以此類推,一直翻轉到最后一個。然后把head的地址引用變成最后一個。
    //在這個鏈表里面,head的位置是一直不變的,它永遠是最前面,在head之后的節點才開始翻轉。
    public void reverseTable(){
        Node node1=head.getnext();
        
        if(node1==null){
            return;
        }
        
        Node preNode=null;
        Node curNode=node1;
        
        while(true){
            Node origNextNode=curNode.getnext();
            curNode.setNext(preNode);
            if(origNextNode==null){
                head.setNext(curNode);
                break;
            }
            preNode=curNode;
            curNode=origNextNode;
        }
        
    }

2.獲得中間節點:

//通過用快慢指針來找到中間節點,快指針的速度為慢指針的兩倍,慢指針一次走一個節點,快指針一次走兩個節點,
    //當快指針走到盡頭時,慢指針剛好為中間值,當快指針走到倒數第二個節點時,慢指針為上中位數。
    //fastPointer!=null用來判斷鏈表表內除head外有沒有其它節點,fastPointer.getnext()!=null判斷是否為最后一個節點,
    //fastPointer.getnext().getnext()!=null判斷是否為倒數第二個節點。
    public String getMid(){
        
        Node slowPointer=this.head.getnext(),fastPointer=this.head.getnext();
        while(fastPointer!=null&&fastPointer.getnext()!=null&&fastPointer.getnext().getnext()!=null){
            slowPointer=slowPointer.getnext();
            fastPointer=fastPointer.getnext().getnext();
        }
        
        return slowPointer.getValue();
        
    }

3.刪除具有相同值的節點(重復節點):

//刪除具有相同值的節點
    //基本原理是用第一個節點的值和第二個節點值比較,然后和第三個節點比較,以此類推。此時第一個節點為當前節點nodeCur,第二第三以及之后的節點為比較節點compareNode
    //一輪比較完畢后,第二個節點就變成nodeCur,之后那些節點就是compareNode
    //如果遇到有相同的值的節點,就將該節點的上個節點的next值為該節點的下個節點:lastNode.setNext(compareNode.getnext()),此時該節點就在鏈表里失去引用了,就相當於刪除了。
    //所以需要lastNode引用來保存當前比較節點的上一個節點
    public void deleteDuplicateNode(){
        Node nodeCur=head.getnext();
        
        if(nodeCur==null) return;
        
        while(nodeCur.getnext()!=null){
            Node lastNode=nodeCur;
            Node compareNode=lastNode.getnext();
            while(compareNode!=null){
                
                if(nodeCur.getValue().equals(compareNode.getValue())){
                    lastNode.setNext(compareNode.getnext());
                    compareNode=compareNode.getnext();
                }else{
                    
                    lastNode=compareNode;
                    compareNode=compareNode.getnext();
                }
            }
            nodeCur=nodeCur.getnext();
        }
    }

 

寫好之后可以測試一下:

public class Test {

    public static void main(String[] args) {

        MyLinkedTable m=new MyLinkedTable();
        m.add("1");
        m.add("2");
        m.add("3");
        m.add("4");
        m.add("5");
        m.add("6");
        
        
        for(int i=1;i<=m.length();i++){
            System.out.println(i+":"+m.get(i));
        }
        System.out.println("length:"+m.length());
        
        m.reverseTable();
        for(int i=1;i<=m.length();i++){
            System.out.println(i+":"+m.get(i));
        }
        System.out.println("length:"+m.length());
        
        m.delete(2);
        for(int i=1;i<=m.length();i++){
            System.out.println(i+":"+m.get(i));
        }
        System.out.println("length:"+m.length());
        
        System.out.println(m.getMid());
        
        
        
    }

}

運行輸出如下:

1:1
2:2
3:3
4:4
5:5
6:6
length:6
1:6
2:5
3:4
4:3
5:2
6:1
length:6
1:6
2:4
3:3
4:2
5:1
length:5
3

還有測試刪除重復節點的:

public class Test2 {

    public static void main(String[] args) {
        MyLinkedTable m=new MyLinkedTable();
        m.add("1");
        m.add("2");
        m.add("3");
        m.add("2");
        m.add("2");
        m.add("6");

        for(int i=1;i<=m.length();i++){
            System.out.println(i+":"+m.get(i));
        }
        System.out.println("length:"+m.length());
        
        m.deleteDuplicateNode();
        
        for(int i=1;i<=m.length();i++){
            System.out.println(i+":"+m.get(i));
        }
        System.out.println("length:"+m.length());
    }

}

運行輸出:

1:1
2:2
3:3
4:2
5:2
6:6
length:6
1:1
2:2
3:3
4:6
length:4

 

 

以上就是用java實現單向無環鏈表的詳細過程和解釋,如果不妥之處,歡迎指出。

 


免責聲明!

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



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