1. 程式人生 > >Java雙向連結串列的實現

Java雙向連結串列的實現

最近在複習Java的基礎知識,看到了List時,想起學習C++時,曾用結構體構造有頭連結串列,所以好奇如何使用Java構造連結串列,遂有了如下程式碼:
實現了連結串列的雙向新增,雙向遍歷,刪除值;
本例中,頭結點和尾節點是單獨出來的,value屬性為null,只是為了方便讀取而存在的,不儲存具體的物件;

//連結串列的節點類,MyNode.java
package my;

public class MyNode<T>
{
    public T value;          //節點值
    public MyNode<T> previous;//前一個,如果沒有這個引數的話,不好從後向前遍歷
public MyNode<T> next; public MyNode(T value) { this.value = value; this.next = null; this.previous = null; } public T getValue() { return value; } public void setValue(T value) { this.value = value; } public
MyNode<T> getPrevious() { return previous; } public void setPrevious(MyNode<T> previous) { this.previous = previous; } public MyNode<T> getNext() { return next; } public void setNext(MyNode<T> next) { this
.next = next; } }
//連結串列的具體實現類:MyList.java 
package my;
//該列表是否可以存放異構物件,去掉本類的泛型是否可以;結論:將T設為Object時,該列表可以存放異構物件,
public class MyList<T>
{ 
    //是否可以先建立一個內部類,在內部類中定義節點屬性;結果:新建了一個節點類,把節點單獨作為一個物件使用;使用內部類也是可以的;
    public MyNode head = new MyNode(null);
    public MyNode last = new MyNode(null);

    public MyList()
    {
        head.previous = null;
        head.next = last;
        last.previous = head;
        last.previous = null;
    }

    public void addtoHead(T value)
    {
        MyNode node = new MyNode(value);
        head.next.previous = node;
        node.next = head.next;
        node.previous = head;
        head.next = node;
    }

    public void addtoLast(T value)
    {
        MyNode node = new MyNode(value);
        last.previous.next = node;
        node.previous = last.previous;
        node.next = last;
        last.previous = node;
    }

    //刪除節點,使用value,如果加上下標的話,就變成hash表了;刪除第一個相同的value
    public void delete(T value) throws Exception
    {
        MyNode node = head.next;
        while(node != null && node != last)
        {
            if(node.getValue() == value)
            {
                //刪除
                node.previous.next = node.next;
                node.next.previous = node.previous;
                node = null;
                break;
            }
            node = node.next;
        }
        boolean isTheLast = node==last;
        if(isTheLast)
        {
            throw new Exception("連結串列中不存在:"+value);
        }       
        //System.out.println("是否為last:"+isTheLast);

    }

    //連結串列的雙向遍歷
    public void printListFromHead() throws Exception
    {
        MyNode node = head.next;
        if(node == last)
        {
            throw new Exception("連結串列為空");
        }
        while(node != null && node != last)
        {
            System.out.println(node.getValue() + "");
            node = node.next;
        }
    }
    public void printListFromLast() throws Exception
    {
        MyNode node = last.previous;
        if(node == head)
        {
            throw new Exception("連結串列為空");
        }
        while(node != null && node != head)
        {
            System.out.println(node.getValue() + "");
            node = node.previous;
        }
    }

    public MyNode getHead()
    {
        return head;
    }

    public void setHead(MyNode head)
    {
        this.head = head;
    }

    public MyNode getLast()
    {
        return last;
    }

    public void setLast(MyNode last)
    {
        this.last = last;
    }
}
//測試類:test1.java
package my;
public class test1
{
    /**
     * 連結串列測試
     * 
     * @param args
     */
    public static void main(String[] args)
    {
        try
        {
            MyList<String> myList1 = new MyList<String>();
            myList1.addtoHead("ppp");
            myList1.addtoHead("ssd");
            myList1.addtoHead("sdf");
            myList1.addtoHead("so");
            myList1.addtoHead("123");
            myList1.addtoHead("ppp");

            System.out.println("-------正向遍歷測試--------");
            myList1.printListFromHead();
            System.out.println("-------反向遍歷測試--------");
            myList1.printListFromLast();

            System.out.println("---------刪除測試------------------------------");
            myList1.delete("ppp");
            myList1.printListFromHead();

            System.out
                    .println("---------是否可以存放異構物件------------------------------");
            MyList<Object> myList2 = new MyList<Object>();
            myList2.addtoHead("sdf");
            myList2.addtoHead(123);
            myList2.addtoHead(2323.23);
            myList2.addtoHead("sdf");
            myList2.addtoHead("123");

            myList2.printListFromHead();

            try
            {
                System.out
                        .println("---------空連結串列異常測試------------------------------");
                MyList<String> myList0 = new MyList<String>();

                myList0.printListFromHead();// 出現異常,直接跳轉至catch中執行;
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        } catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}