1. 程式人生 > >手寫雙向連結串列

手寫雙向連結串列

採用雙向連結串列的形式嘗試寫一下 java中LinkedList

public class LinkedList<E> {


    /**
     * 節點
     */
    private static class Node<E> {
        E item;
        Node<E> pre;
        Node<E> next;

        public Node(Node<E> pre, E item, Node<E> next) {
            this.item = item;
            this.pre = pre;
            this.next = next;
        }
    }


    public LinkedList() {
    }

    //頭節點
    Node<E> first;
    //尾節點
    Node<E> last;
    //大小
    int size;


    /**
     * 新增資料在最後
     */
    public void add(E e) {
        linkLast(e);
    }

    /**
     * 新增到最後
     *
     * @param e
     */
    private void linkLast(E e) {
        Node<E> newNode = new Node<>(last, e, null);
        Node<E> temp = last;
        last = newNode;

        if (temp == null) {
            first = newNode;
        } else {
            temp.next = newNode;
        }
        size++;
    }

    /**
     * 獲取物件
     */
    public E get(int index) {
        if (index < 0 || index > size - 1) {
            return null;
        }
        return node(index).item;
    }

    /**
     * 獲取index位置上的節點
     *
     * @param index
     */
    private Node<E> node(int index) {
        Node<E> node;
        //如果index在連結串列前半部分
        if (index < (size >> 1))//除以2
        {
            node = first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
        } else {
            node = last;
            for (int i = size - 1; i > index; i--) {
                node = node.pre;
            }
        }
        return node;
    }


    /**
     * 新增資料在index位置
     */

    public void add(int index, E e) {
        if (index < 0 || index > size) {
            return;
        }

        if (index == size) {
            linkLast(e);
        } else {
            Node<E> target = node(index);
            Node<E> preNode = target.pre;
            Node<E> newNode = new Node<>(preNode, e, target);

            if (preNode == null) {
                first = newNode;
                target.pre = newNode;
            } else {
                preNode.next = newNode;
                target.pre = newNode;
            }
            size++;
        }
    }

    /**
     * 刪除元素
     */
    public void remove(int index) {
        if (size == 0 || index < 0 || index > size - 1) {
            return;
        }
        Node<E> node = node(index);
        unLinkNode(node);
    }

    private void unLinkNode(Node<E> node) {
        Node<E> preNode = node.pre;
        Node<E> nextNode = node.next;

        if (preNode == null) {
            first = nextNode;
        } else if (nextNode == null) {
            last = preNode;
        } else {
            preNode.next = nextNode;
            nextNode.pre = preNode;
        }
        size--;
    }

}

 

寫個test測試下功能 

 @Test
    public void testLinkedList(){

        LinkedList<Integer> list=new LinkedList<>();
        list.add(3);
        list.add(80);
        list.add(1);
        list.add(7);
        list.add(32);
        log(list);
        list.add(0,12);
        log(list);

        list.add(3,50);
        log(list);

        list.remove(3);
        log(list);

        list.remove(0);
        log(list);
    }

    public void log(LinkedList linkedList){
        for (int i = 0; i < linkedList.size; i++) {
            System.out.print(linkedList.get(i)+" ");
        }
        System.out.println("");
    }

 列印結果

3 80 1 7 32 
12 3 80 1 7 32 
12 3 80 50 1 7 32 
12 3 80 1 7 32 
3 80 1 7 32 

判斷單鏈表是否存在環?

【快慢指標】:需要兩個指標,一個快指標:每次走兩步,一個慢指標:每次走一步。 
如果快慢指標能夠相遇(如果快指標能夠追上慢指標),就證明有環。 
但是!!!這個方法存在問題。如果連結串列夠長,而環又足夠小,那麼快指標將永遠不會追上慢指標 
所以,快慢指標只適合用於環出現在連結串列尾部的情況,也就是單鏈表環的問題,而無法解決連結串列存在迴圈的問題。
 

   public class Link_list_circle {

        public boolean hascycle(ListNode head) {
            //快慢指標
            ListNode slow, fast;
            slow = fast = head;
            while (fast != null && fast.next != null) {
                slow = slow.next;
                fast = fast.next.next;
                if (fast == slow) return ture;
            }
            return false;
        }

    }