1. 程式人生 > >Java 連結串列 連結串列反轉

Java 連結串列 連結串列反轉

連結串列:單向連結串列 雙向連結串列 單向迴圈連結串列 雙向迴圈連結串列 連結串列的反轉.


定義了連結串列的基本使用, 對連結串列增加了索引, 使用兩種方式(遞迴和迴圈)對連結串列進行反轉操作.


單向連結串列:



public class SinglyChain<E> {
    private Object lock = new Object();


    private Node head;// 頭節點
    private Node last;// 尾節點
    private int size;


    public int size() {
        return size;
    }


    /**
     * 允許新增的物件重複, 預設新增到末尾;<br/>
     * 不允許新增空物件
     */
    public boolean add(E data) {
        synchronized (lock) {
            if (data != null) {
                Node node = new Node(size, data);
                if (size == 0) {
                    head = node;
                } else {
                    last.next = node;
                }


                last = node;
                size++;
                return true;
            }
            return false;
        }
    }


    /**
     * 允許新增的物件重複, 預設新增到末尾;<br/>
     * 不允許新增空物件
     * 
     * @param index 新增的位置索引
     */
    public boolean add(int index, E data) {
        if (index < 0) {
            index = 0;
        } else if (index > size) {
            index = size;
        }
        synchronized (lock) {
            if (data != null) {
                if (index == size) {
                    return add(data);
                } else {
                    Node newNode = new Node(index, data);
                    Node node = head;
                    Node pre = null;
                    while (node != null) {
                        if (node.index == index) {


                            if (node == head) {
                                newNode.next = head;
                                head = newNode;
                            } else {
                                pre.next = newNode;
                                newNode.next = node;
                            }


                            moveToBack(node);
                            size++;
                            return true;
                        }


                        pre = node;
                        node = node.next;
                    }


                }
            }
            return false;
        }
    }


    /** 如果添加了重複物件,則只刪除遍歷到的第一個 */
    public boolean remove(E data) {
        synchronized (lock) {
            if (data != null) {
                Node currentNode = head;
                Node preNode = null;
                Node nextNode;


                while (currentNode != null) {
                    nextNode = currentNode.next;
                    if (currentNode.data == data) {
                        if (preNode == null) {
                            // 如果刪除的是首節點, 重置首節點
                            head = nextNode;
                        } else {
                            // 將需要刪除的物件 currentNode 從連結串列中剔除
                            preNode.next = nextNode;
                        }


                        // 如果刪除的是尾節點, 重置尾節點
                        if (currentNode == last) {
                            last = preNode;
                        }


                        // 將node中的index進行移位操作
                        moveToFront(nextNode);
                        size--;
                        return true;
                    }


                    preNode = currentNode;
                    currentNode = currentNode.next;
                }
            }
            return false;
        }
    }


    /** 根據索引位置刪除連結串列中的物件 */
    public boolean remove(int index) {


        synchronized (lock) {
            Node currentNode = head;
            Node preNode = null;
            Node nextNode;


            while (currentNode != null) {
                nextNode = currentNode.next;
                if (currentNode.index == index) {
                    if (preNode == null) {
                        // 如果刪除的是首節點, 重置首節點
                        head = nextNode;
                    } else {
                        // 將需要刪除的物件 currentNode 從連結串列中剔除
                        preNode.next = nextNode;
                    }


                    // 如果刪除的是尾節點, 重置尾節點
                    if (currentNode == last) {
                        last = preNode;
                    }


                    // 將node中的index進行移位操作
                    moveToFront(nextNode);
                    size--;
                    return true;
                }


                preNode = currentNode;
                currentNode = currentNode.next;
            }
            return false;
        }
    }


    public E get(int index) {
        if (index < 0 || index > size - 1) {
            throw new IndexOutOfBoundsException();
        }


        Node node = head;
        while (node != null) {
            if (node.index == index) {
                return node.data;
            }
        }
        return null;
    }


    public E getFirst() {
        return head.data;
    }


    public E getLast() {
        return last.data;
    }


    /** 將當前節點以後的所有節點索引前移一位 */
    private void moveToFront(Node node) {
        synchronized (lock) {
            while (node != null) {
                node.setIndex(node.getIndex() - 1);
                node = node.next;
            }
        }
    }


    /** 將當前節點以後的所有節點索引後移一位 */
    private void moveToBack(Node node) {
        while (node != null) {
            node.setIndex(node.getIndex() + 1);
            node = node.next;
        }
    }


    @Override
    public String toString() {
        if (head == null && head == last) {
            return "NodeChain {}";
        }


        StringBuilder sb = new StringBuilder();
        // 將所有的子節點遞迴處理
        Node node = head;
        sb.append("NodeChain {");
        while (node != null) {
            sb.append("\n")
                    .append('[')
                    .append(node.toString())
                    .append(']')
                    .append(',')
                    .append(' ');
            node = node.next;
        }
        sb.append('}');
        return sb.toString();
    }


    /** 翻轉連結串列 */
    public void reverseChain() {
        Node reverse = reverseCycle(head);


        // 首尾置換
        head = last;
        last = reverse;


        last.next = null;


        last.index = size - 1;
    }


    /** 遞迴反轉連結串列 */
    private Node reverseRecursion(Node node) {
        if (node.next == null) {// 尾節點
            return node;
        }
        Node temp = reverseRecursion(node.next);
        temp.next = node;
        temp.index = size - 1 - temp.index;


        return node;
    }


    /** 迴圈反轉連結串列 */
    private Node reverseCycle(Node head) {
        if (head == null) {
            return null;
        }


        Node pre = head;
        Node cur = pre.next;
        Node next;


        while (cur != null) {
            next = cur.next;
            cur.next = pre;
            cur.index = size - 1 - cur.index;
            pre = cur;
            cur = next;
        }


        return head;
    }


    class Node {
        int index;
        Node next;
        E data;


        public Node(int index, E data) {
            super();
            this.index = index;
            this.data = data;
        }


        public int getIndex() {
            return index;
        }


        public void setIndex(int index) {
            this.index = index;
        }


        @Override
        public String toString() {
            String str = "Node {index:" + index + ", data : " + data.toString() + '}';
            if (next != null) {
                str += " -> next = " + next.data + ", next.index = " + next.index;
            }
            return str;
        }
    }


}

單向迴圈連結串列:



public class SinglyCircleChain<E> {
    private Object lock = new Object();


    private Node head;// 頭節點
    private Node last;// 尾節點
    private int size;


    public int size() {
        return size;
    }


    /**
     * 允許新增的物件重複, 預設新增到末尾;<br/>
     * 不允許新增空物件
     */
    public boolean add(E data) {
        synchronized (lock) {
            if (data != null) {
                Node node = new Node(size, data);
                if (size == 0) {
                    head = node;
                } else {
                    last.next = node;
                }


                last = node;
                last.next = head;
                size++;
                return true;
            }
            return false;
        }
    }


    /**
     * 允許新增的物件重複, 預設新增到末尾;<br/>
     * 不允許新增空物件
     * 
     * @param index 新增的位置索引
     */
    public boolean add(int index, E data) {
        synchronized (lock) {
            if (index < 0 || index > size) {
                throw new IndexOutOfBoundsException();
            }


            if (data != null) {
                if (index == size) {
                    return add(data);
                } else {
                    Node newNode = new Node(index, data);
                    Node node = head;
                    Node pre = last;


                    while (node != null) {
                        if (node.index == index) {
                            if (node == head) {// 首節點
                                newNode.next = node;
                                head = newNode;
                                last.next = newNode;
                            } else {
                                pre.next = newNode;
                                newNode.next = node;
                            }


                            moveToBack(node);
                            size++;
                            return true;
                        }


                        pre = node;
                        node = node.next;


                        if (node == head) {
                            break;
                        }
                    }


                }
            }
            return false;
        }
    }


    /** 如果添加了重複物件,則只刪除遍歷到的第一個 */
    public boolean remove(E data) {
        synchronized (lock) {
            if (data != null && head != null) {
                Node currentNode = head;
                Node preNode = null;
                Node nextNode;


                while (currentNode != null) {
                    nextNode = currentNode.next;
                    if (currentNode.data == data) {
                        if (preNode == null) {
                            // 如果刪除的是首節點, 重置首節點
                            head = nextNode;
                        } else {
                            // 將需要刪除的物件 currentNode 從連結串列中剔除
                            preNode.next = nextNode;
                        }


                        // 如果刪除的是尾節點, 重置尾節點
                        if (currentNode == last) {
                            last = preNode;
                        }


                        // 將node中的index進行移位操作
                        moveToFront(nextNode);
                        size--;
                        return true;
                    }


                    preNode = currentNode;
                    currentNode = currentNode.next;


                    if (currentNode == head) {
                        break;
                    }
                }
            }
            return false;
        }
    }


    /** 根據索引位置刪除連結串列中的物件 */
    public boolean remove(int index) {


        synchronized (lock) {
            Node currentNode = head;
            Node preNode = null;
            Node nextNode;


            while (currentNode != null) {
                nextNode = currentNode.next;
                if (currentNode.index == index) {
                    if (preNode == null) {
                        // 如果刪除的是首節點, 重置首節點
                        head = nextNode;
                    } else {
                        // 將需要刪除的物件 currentNode 從連結串列中剔除
                        preNode.next = nextNode;
                    }


                    // 如果刪除的是尾節點, 重置尾節點
                    if (currentNode == last) {
                        last = preNode;
                        last.next = head;
                    }


                    // 將node中的index進行移位操作
                    moveToFront(nextNode);
                    size--;
                    return true;
                }


                preNode = currentNode;
                currentNode = currentNode.next;


                if (currentNode == head) {
                    break;
                }
            }
            return false;
        }
    }


    public E get(int index) {
        if (index < 0 || index > size - 1) {
            throw new IndexOutOfBoundsException();
        }


        Node node = head;
        while (node != null) {
            if (node.index == index) {
                return node.data;
            }
        }
        return null;
    }


    /** 將當前節點以後的所有節點索引前移一位 */
    private void moveToFront(Node node) {
        synchronized (lock) {
            while (node != null) {
                node.setIndex(node.getIndex() - 1);
                node = node.next;
                if (node == head) {
                    break;
                }
            }
        }
    }


    /** 將當前節點以後的所有節點索引後移一位 */
    private void moveToBack(Node node) {
        while (node != null) {
            node.setIndex(node.getIndex() + 1);
            node = node.next;
            if (node == head) {
                break;
            }
        }
    }


    /** 翻轉連結串列 */
    public void reverseChain() {
        Node reverse = reverseCycle(head);


        // 首尾置換
        head = last;
        last = reverse;


        last.next = head;


        last.index = size - 1;
    }


    /** 遞迴反轉連結串列 */
    private Node reverseRecursion(Node node) {
        if (node.next == head) {// 尾節點
            return node;
        }


        Node temp = reverseRecursion(node.next);
        temp.next = node;
        temp.index = size - 1 - temp.index;


        return node;
    }


    /** 迴圈反轉連結串列 */
    private Node reverseCycle(Node head) {
        if (head == null) {
            return null;
        }


        Node pre = head;
        Node cur = pre.next;
        Node next;


        while (cur != head) {
            next = cur.next;
            cur.next = pre;
            cur.index = size - 1 - cur.index;
            pre = cur;
            cur = next;
        }


        return head;
    }


    @Override
    public String toString() {
        if (head == null && head == last) {
            return "NodeChain {}";
        }


        StringBuilder sb = new StringBuilder();
        // 將所有的子節點遞迴處理
        Node node = head;
        sb.append("NodeChain {");
        while (node != null) {
            sb.append("\n")
                    .append('[')
                    .append(node.toString())
                    .append(']')
                    .append(',')
                    .append(' ');
            node = node.next;
            if (node == head) {
                break;
            }
        }
        sb.append('}');
        return sb.toString();
    }


    class Node {
        int index;
        Node next;
        E data;


        public Node(int index, E data) {
            super();
            this.index = index;
            this.data = data;
        }


        public int getIndex() {
            return index;
        }


        public void setIndex(int index) {
            this.index = index;
        }


        @Override
        public String toString() {
            String str = "Node {index:" + index + ", data : " + data.toString() + '}';
            str += " -> next = " + next.data + ", next.index = " + next.index;
            return str;
        }
    }


}

雙向連結串列:

public class DoublyChain<E> {
    private Object lock = new Object();


    private Node head;// 頭節點
    private Node last;// 尾節點
    private int size;


    public int gsize() {
        return size;
    }


    /**
     * 允許新增的物件重複, 預設新增到末尾;<br/>
     * 不允許新增空物件
     */
    public boolean add(E data) {
        synchronized (lock) {
            if (data != null) {
                Node node = new Node(size, data);
                if (size == 0) {
                    head = node;
                } else {
                    last.next = node;
                    node.previous = last;
                }


                last = node;
                size++;
                return true;
            }
            return false;
        }
    }


    /**
     * 允許新增的物件重複, 預設新增到末尾;<br/>
     * 不允許新增空物件
     * 
     * @param index 新增的位置索引
     */
    public boolean add(int index, E data) {
        if (index < 0) {
            index = 0;
        } else if (index > size) {
            index = size;
        }
        synchronized (lock) {
            if (data != null) {
                if (index == size) {
                    return add(data);
                } else {
                    Node newNode = new Node(index, data);
                    Node nextNode = head;// 相對於新插入位置後一個
                    Node preNode = null;// 相對於新插入位置前一個
                    while (nextNode != null) {
                        if (nextNode.index == index) {
                            if (head == nextNode) {
                                head = newNode;
                            }


                            if (preNode != null) {
                                preNode.next = newNode;
                            }


                            if (nextNode != null) {
                                nextNode.previous = newNode;
                            }


                            newNode.previous = preNode;
                            newNode.next = nextNode;


                            moveToBack(nextNode);
                            size++;
                            return true;
                        }
                        preNode = nextNode;
                        nextNode = nextNode.next;
                    }


                }
            }
            return false;
        }
    }


    /** 如果添加了重複物件,則只刪除遍歷到的第一個 */
    public boolean remove(E data) {
        synchronized (lock) {
            if (data != null) {
                Node currentNode = head;
                Node preNode = null;
                Node nextNode;


                while (currentNode != null) {
                    nextNode = currentNode.next;
                    if (currentNode.data == data) {
                        if (preNode == null) {
                            // 如果刪除的是首節點, 重置首節點
                            head = nextNode;
                            head.previous = null;
                        } else {
                            // 將需要刪除的物件 currentNode 從連結串列中剔除
                            preNode.next = nextNode;
                            if (nextNode != null) {// 非尾節點
                                nextNode.previous = preNode;
                            }
                        }


                        // 如果刪除的是尾節點, 重置尾節點
                        if (currentNode == last) {
                            last = preNode;
                            last.next = null;
                        }


                        // 將node中的index進行移位操作
                        moveToFront(nextNode);
                        size--;
                        return true;
                    }


                    preNode = currentNode;
                    currentNode = currentNode.next;
                }
            }
            return false;
        }
    }


    /**
     * 根據索引位置刪除連結串列中的物件<br>
     * 如果索引超出界限將刪除失敗
     */
    public boolean remove(int index) {
        synchronized (lock) {
            Node currentNode = head;
            Node preNode = null;
            Node nextNode;


            while (currentNode != null) {
                nextNode = currentNode.next;
                if (currentNode.index == index) {
                    if (preNode == null) {
                        // 如果刪除的是首節點, 重置首節點
                        head = nextNode;
                        head.previous = null;
                    } else {
                        // 將需要刪除的物件 currentNode 從連結串列中剔除
                        preNode.next = nextNode;
                        if (nextNode != null) {
                            nextNode.previous = preNode;
                        }
                    }


                    // 如果刪除的是尾節點, 重置尾節點
                    if (currentNode == last) {
                        last = preNode;
                        last.next = null;
                    }


                    // 將node中的index進行移位操作
                    moveToFront(nextNode);
                    size--;
                    return true;
                }


                preNode = currentNode;
                currentNode = currentNode.next;
            }
            return false;
        }
    }


    public E get(int index) {
        if (index < 0 || index > size - 1) {
            throw new IndexOutOfBoundsException();
        }


        Node node = head;
        while (node != null) {
            if (node.index == index) {
                return node.data;
            }
        }
        return null;
    }


    /** 將當前節點以後的所有節點索引前移一位 */
    private void moveToFront(Node node) {
        synchronized (lock) {
            while (node != null) {
                node.setIndex(node.getIndex() - 1);
                node = node.next;
            }
        }
    }


    /** 將當前節點以後的所有節點索引後移一位 */
    private void moveToBack(Node node) {
        while (node != null) {
            node.setIndex(node.getIndex() + 1);
            node = node.next;
        }
    }


    /** 翻轉連結串列 */
    public void reverseChain() {
        Node reverse = reverseCycle(head);


        // 首尾置換
        head = last;


        last = reverse;


        head.previous = null;
        last.next = null;


        last.index = size - 1;
    }


    /** 遞迴反轉連結串列 */
    private Node reverseRecursion(Node node) {
        if (node.next == null) {// 尾節點
            return node;
        }
        Node temp = reverseRecursion(node.next);
        temp.next = node;
        node.previous = temp;
        temp.index = size - 1 - temp.index;


        return node;
    }


    /** 迴圈反轉連結串列 */
    private Node reverseCycle(Node head) {
        if (head == null) {
            return null;
        }


        Node pre = head;
        Node cur = pre.next;
        Node next;


        while (cur != null) {
            next = cur.next;
            cur.next = pre;
            pre.previous = cur;


            cur.index = size - 1 - cur.index;
            pre = cur;
            cur = next;
        }


        return head;
    }


    @Override
    public String toString() {
        if (head == null && head == last) {
            return "NodeChain {}";
        }


        StringBuilder sb = new StringBuilder();
        // 將所有的子節點遞迴處理
        Node node = head;
        sb.append("NodeChain {");
        while (node != null) {
            sb.append('\n')
                    .append('[')
                    .append(node.toString())
                    .append(']')
                    .append(',');
            node = node.next;
        }
        sb.append('}');
        return sb.toString();
    }


    class Node {
        int index;
        E data;


        Node next;
        Node previous;


        public Node(int index, E data) {
            super();
            this.index = index;
            this.data = data;
        }


        public int getIndex() {
            return index;
        }


        public void setIndex(int index) {
            this.index = index;
        }


        @Override
        public String toString() {
            String str = "Node {index:" + index + ", data : " + data.toString() + '}';


            if (next != null) {
                str += ", next = " + next.index;
            } else {
                str += ", next is empty";
            }


            if (previous != null) {
                str += ", previous = " + previous.index;
            } else {
                str += ", previous is empty";
            }
            return str;
        }
    }


}

雙向迴圈連結串列:



public class DoublyCircleChain<E> {
    private Object lock = new Object();


    private Node head;// 頭節點
    private Node last;// 尾節點
    private int size;


    public int gsize() {
        return size;
    }


    /**
     * 允許新增的物件重複, 預設新增到末尾;<br/>
     * 不允許新增空物件
     */
    public boolean add(E data) {
        synchronized (lock) {
            if (data != null) {
                Node node = new Node(size, data);
                if (size == 0) {
                    head = node;
                } else {
                    last.next = node;
                    node.previous = last;
                }


                last = node;


                last.next = head;
                head.previous = last;


                size++;
                return true;
            }
            return false;
        }
    }


    /**
     * 允許新增的物件重複, 預設新增到末尾;<br/>
     * 不允許新增空物件
     * 
     * @param index 新增的位置索引
     */
    public boolean add(int index, E data) {
        if (index < 0) {
            index = 0;
        } else if (index > size) {
            index = size;
        }
        synchronized (lock) {
            if (data != null) {
                if (index == size) {
                    return add(data);
                } else {
                    Node newNode = new Node(index, data);
                    Node nextNode = head;// 相對於新插入位置後一個
                    Node preNode = last;// 相對於新插入位置前一個
                    while (nextNode != null) {
                        if (nextNode.index == index) {
                            if (head == nextNode) {
                                head = newNode;
                            }


                            if (preNode != null) {
                                preNode.next = newNode;
                            }


                            if (nextNode != null) {
                                nextNode.previous = newNode;
                            }


                            newNode.previous = preNode;
                            newNode.next = nextNode;


                            moveToBack(nextNode);
                            size++;
                            return true;
                        }
                        preNode = nextNode;
                        nextNode = nextNode.next;


                        if (nextNode == head) {
                            break;
                        }
                    }


                }
            }
            return false;
        }
    }


    /** 如果添加了重複物件,則只刪除遍歷到的第一個 */
    public boolean remove(E data) {
        synchronized (lock) {
            Node currentNode = head;
            Node preNode = last;
            Node nextNode;


            int index = 0;
            while (currentNode != null) {
                index++;
                nextNode = currentNode.next;
                if (currentNode.data == data) {
                    if (preNode == last) {
                        // 如果刪除的是首節點, 重置首節點
                        head = nextNode;
                        head.previous = last;
                    } else {
                        // 將需要刪除的物件 currentNode 從連結串列中剔除
                        preNode.next = nextNode;
                        nextNode.previous = preNode;
                    }


                    // 如果刪除的是尾節點, 重置尾節點
                    if (currentNode == last) {
                        last = preNode;
                        last.next = head;
                    }


                    last.next = head;
                    head.previous = last;


                    if (index != size) {// 如果刪除的是最後一個,則不進行索引移動
                        // 將node中的index進行移位操作
                        moveToFront(nextNode);
                    }
                    size--;
                    return true;
                }


                preNode = currentNode;
                currentNode = currentNode.next;


                if (currentNode == head) {
                    break;
                }
            }
            return false;
        }
    }


    /**
     * 根據索引位置刪除連結串列中的物件<br>