算法(Algorithms)第4版 练习 1.3.31

双向链表实现:

//1.3.31
package com.qiusongde.linkedlist;

public class DoublyLinkedList<Item> {
    
    private DoublyNode<Item> first;
    private DoublyNode<Item> last;
    
    //can be accessed outside this class
    public static class DoublyNode<E>    {
        public E item;
        public DoublyNode<E> next;
        public DoublyNode<E> pre;
    }
    
    public DoublyLinkedList() {
        first = null;
        last = null;
    }
    
    /**
     * insert item at the beginning of the list
     * 
     * @param list the list to insert
     * @param item the item to be inserted
     */
    public static <T> void insertAtBeginning(DoublyLinkedList<T> list, T item) {
        
        DoublyNode<T> oldfirst = list.first;//save old first node
        
        list.first = new DoublyNode<T>();//new first node
        list.first.item = item;//save item
        list.first.next = oldfirst;//point to oldfirst
        list.first.pre = null;//pre initialize to null
        
        if(oldfirst != null) {
            oldfirst.pre = list.first;
        } else {//oldfirst is null
            list.last = list.first;
        }

    }
    
    /**
     * insert item at the end of the list
     * 
     * @param list the list to insert
     * @param item the item to be inserted
     */
    public static <T> void insertAtTheEnd(DoublyLinkedList<T> list, T item) {
        
        DoublyNode<T> oldlast = list.last;
        
        list.last = new DoublyNode<T>();
        list.last.item = item;
        list.last.next = null;
        list.last.pre = oldlast;
        
        if(oldlast == null) {
            list.first = list.last;
        } else {
            oldlast.next = list.last;
        }
        
    }
    
    /**
     * remove the first node in the list. If the first node in the list is null, then do nothing.
     * 
     * @param list the list whose first node will be removed
     */
    public static <T> void removeFromBeginning(DoublyLinkedList<T> list) {
        
        if(list.first == null) {
            return;//do nothing
        }
        
        list.first = list.first.next;//new position for first
        if(list.first == null) {//not more leave
            list.last = null;
        } else {
            list.first.pre.next = null;
            list.first.pre = null;
        }
        
    }
    
    /**
     * remove the last node in the list. If the last node in the list is null, then do nothing.
     * 
     * @param list the list whose last node will be removed
     */
    public static <T> void removeFromTheEnd(DoublyLinkedList<T> list) {
        
        if(list.last == null) {
            return;//do nothing
        }
        
        list.last = list.last.pre;
        if(list.last == null) {
            list.first = null;
        } else {
            list.last.next.pre = null;
            list.last.next = null;
        }
        
    }
    
    public static <T> DoublyNode<T> findDoublyNode(DoublyLinkedList<T> list, T item) {
        DoublyNode<T> current = list.first;
        
        while(current != null) {
            if(current.item.equals(item)) {
                break;
            }
            current = current.next;
        }
        
        return current;
    }
    
    /**
     * insert the item before the node in the list. if node is null or node isn't in the list, then do nothing.
     * 
     * @param list the list in which the node is
     * 
     * @param node the node before which the item will be inserted 
     * 
     * @param item the item to be inserted
     */
    public static <T> void insertBeforeNode(DoublyLinkedList<T> list, DoublyNode<T> node, T item) {
        
        if(node == null) {//do nothing
            return;
        }
        
        if(isInList(list, node)) {//node is in list
            DoublyNode<T> newnode = new DoublyNode<T>();
            newnode.item = item;
            
            newnode.next = node;
            if(node.pre != null) {//not first node in the list
                node.pre.next = newnode;
            } else {//first node in the list
                list.first = newnode;//change first node
            }
            newnode.pre = node.pre;
            node.pre = newnode;//should be last assign
        }
        
    }
    
    /**
     * insert the item after the node in the list. if node is null or node isn't in the list, then do nothing.
     * 
     * @param list the list in which the node is
     * 
     * @param node the node after which the item will be inserted 
     * 
     * @param item the item to be inserted
     */
    public static <T> void insertAfterNode(DoublyLinkedList<T> list, DoublyNode<T> node, T item) {
        
        if(node == null) {//do nothing
            return;
        }
        
        if(isInList(list, node)) {
            DoublyNode<T> newnode = new DoublyNode<T>();
            newnode.item = item;
            
            newnode.pre = node;
            if(node.next != null) {//not last node in the list
                node.next.pre = newnode;
            } else {//last node in the list
                list.last = newnode;
            }
            newnode.next = node.next;
            node.next = newnode;//should be last assign
        }
        
    }
    
    /**
     * remove the node in the list 
     * 
     * @param list the list in which the node is 
     * @param node the node to be removed
     */
    public static <T> void removeNode(DoublyLinkedList<T> list, DoublyNode<T> node) {
        
        if(node == null) {
            return;
        }
        
        if(isInList(list, node)) {
            if(list.first == node) {
                removeFromBeginning(list);
            }
            else if(list.last == node) {
                removeFromTheEnd(list);
            }
            else {
                node.pre.next = node.next;
                node.next.pre = node.pre;
            }
        }
        
    }
    
    /**
     * see if the node is in the list
     * 
     * @param list the list 
     * @param node the node
     * @return {@code true} the node is in the list
     *            {@code false} the node isn't in the list
     */
    public static <T> boolean isInList(DoublyLinkedList<T> list, DoublyNode<T> node) {
        
        DoublyNode<T> current = list.first;
        
        while(current != null) {
            if(current == node) {
                return true;
            }
            current = current.next;
        }
        
        return false;
    }
    
    @Override
    public String toString() {
        String s = "";
        
        DoublyNode<Item> current = first;
        while(current != null) {
            s += current.item + " ";
            current = current.next;
        }
        
        s += first == null ? "first:null " : "first:" + first.item + " ";
        s += last == null ? "last:null " : "last:" + last.item + " ";
        
        return s;
    }

}

测试用例:

package com.qiusongde.linkedlist;

import com.qiusongde.linkedlist.DoublyLinkedList.DoublyNode;

import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

public class Exercise1331 {

    public static void main(String[] args) {
        
        DoublyLinkedList<Integer> list = new DoublyLinkedList<Integer>();
        StdOut.println("Initial doublylist:");
        StdOut.println(list);
        StdOut.println();
        
        //test insertAtBeginning function
        StdOut.println("Test insertAtBeginning function");
        for(int i = 1; i <= 10; i++) {
            DoublyLinkedList.insertAtBeginning(list, i);
            StdOut.println("insertAtBeginning success: " + i);
            StdOut.println(list);
        }
        StdOut.println();
        
        //test removeFromBeginning function
        StdOut.println("Test removeFromBeginning function");
        for(int i = 1; i <= 11; i++) {
            DoublyLinkedList.removeFromBeginning(list);
            StdOut.println("removeFromBeginning success: ");
            StdOut.println(list);
        }
        StdOut.println();
        
        //test insertAtTheEnd function
        StdOut.println("Test insertAtTheEnd function");
        for(int i = 1; i <= 10; i++) {
            DoublyLinkedList.insertAtTheEnd(list, i);
            StdOut.println("insertAtTheEnd success: " + i);
            StdOut.println(list);
        }
        StdOut.println();
        
        //test removeFromTheEnd function
        StdOut.println("Test removeFromTheEnd function");
        for(int i = 1; i <= 11; i++) {
            DoublyLinkedList.removeFromTheEnd(list);
            StdOut.println("removeFromTheEnd success: ");
            StdOut.println(list);
        }
        StdOut.println();
        
        //test insertBeforeNode function
        StdOut.println("Test insertBeforeNode function");
        for(int i = 1; i <= 10; i++) {
            DoublyLinkedList.insertAtBeginning(list, i);
        }
        StdOut.println("Initial list:");
        StdOut.println(list);
        for(int i = 0; i < 10; i++) {
            int number = StdRandom.uniform(10 + i) + 1;
            DoublyNode<Integer> node = DoublyLinkedList.findDoublyNode(list, number);
            DoublyLinkedList.insertBeforeNode(list, node, 11 + i);
            StdOut.println("insert " + (11+i) +  " BeforeNode " +  node.item + " success");
            StdOut.println(list);
        }
        StdOut.println();
        
        //test remove
        StdOut.println("Test removeNode function");
        for(int i = 0; i < 20; i++) {
            DoublyNode<Integer> node = DoublyLinkedList.findDoublyNode(list, i + 1);
            DoublyLinkedList.removeNode(list, node);
            StdOut.println("removeNode success:" + (i+1));
            StdOut.println(list);
        }
        StdOut.println();
        
        //test insertAfterNode function
        StdOut.println("Test insertAfterNode function");
        for(int i = 1; i <= 10; i++) {
            DoublyLinkedList.insertAtBeginning(list, i);
        }
        StdOut.println("Initial list:");
        StdOut.println(list);
        for(int i = 0; i < 10; i++) {
            int number = StdRandom.uniform(10 + i) + 1;
            DoublyNode<Integer> node = DoublyLinkedList.findDoublyNode(list, number);
            DoublyLinkedList.insertAfterNode(list, node, 11 + i);
            StdOut.println("insert " + (11+i) +  " AfterNode " +  node.item + " success");
            StdOut.println(list);
        }
        StdOut.println();
        
    }

}

结果输出:

Initial doublylist:
first:null last:null 

Test insertAtBeginning function
insertAtBeginning success: 1
1 first:1 last:1 
insertAtBeginning success: 2
2 1 first:2 last:1 
insertAtBeginning success: 3
3 2 1 first:3 last:1 
insertAtBeginning success: 4
4 3 2 1 first:4 last:1 
insertAtBeginning success: 5
5 4 3 2 1 first:5 last:1 
insertAtBeginning success: 6
6 5 4 3 2 1 first:6 last:1 
insertAtBeginning success: 7
7 6 5 4 3 2 1 first:7 last:1 
insertAtBeginning success: 8
8 7 6 5 4 3 2 1 first:8 last:1 
insertAtBeginning success: 9
9 8 7 6 5 4 3 2 1 first:9 last:1 
insertAtBeginning success: 10
10 9 8 7 6 5 4 3 2 1 first:10 last:1 

Test removeFromBeginning function
removeFromBeginning success: 
9 8 7 6 5 4 3 2 1 first:9 last:1 
removeFromBeginning success: 
8 7 6 5 4 3 2 1 first:8 last:1 
removeFromBeginning success: 
7 6 5 4 3 2 1 first:7 last:1 
removeFromBeginning success: 
6 5 4 3 2 1 first:6 last:1 
removeFromBeginning success: 
5 4 3 2 1 first:5 last:1 
removeFromBeginning success: 
4 3 2 1 first:4 last:1 
removeFromBeginning success: 
3 2 1 first:3 last:1 
removeFromBeginning success: 
2 1 first:2 last:1 
removeFromBeginning success: 
1 first:1 last:1 
removeFromBeginning success: 
first:null last:null 
removeFromBeginning success: 
first:null last:null 

Test insertAtTheEnd function
insertAtTheEnd success: 1
1 first:1 last:1 
insertAtTheEnd success: 2
1 2 first:1 last:2 
insertAtTheEnd success: 3
1 2 3 first:1 last:3 
insertAtTheEnd success: 4
1 2 3 4 first:1 last:4 
insertAtTheEnd success: 5
1 2 3 4 5 first:1 last:5 
insertAtTheEnd success: 6
1 2 3 4 5 6 first:1 last:6 
insertAtTheEnd success: 7
1 2 3 4 5 6 7 first:1 last:7 
insertAtTheEnd success: 8
1 2 3 4 5 6 7 8 first:1 last:8 
insertAtTheEnd success: 9
1 2 3 4 5 6 7 8 9 first:1 last:9 
insertAtTheEnd success: 10
1 2 3 4 5 6 7 8 9 10 first:1 last:10 

Test removeFromTheEnd function
removeFromTheEnd success: 
1 2 3 4 5 6 7 8 9 first:1 last:9 
removeFromTheEnd success: 
1 2 3 4 5 6 7 8 first:1 last:8 
removeFromTheEnd success: 
1 2 3 4 5 6 7 first:1 last:7 
removeFromTheEnd success: 
1 2 3 4 5 6 first:1 last:6 
removeFromTheEnd success: 
1 2 3 4 5 first:1 last:5 
removeFromTheEnd success: 
1 2 3 4 first:1 last:4 
removeFromTheEnd success: 
1 2 3 first:1 last:3 
removeFromTheEnd success: 
1 2 first:1 last:2 
removeFromTheEnd success: 
1 first:1 last:1 
removeFromTheEnd success: 
first:null last:null 
removeFromTheEnd success: 
first:null last:null 

Test insertBeforeNode function
Initial list:
10 9 8 7 6 5 4 3 2 1 first:10 last:1 
insert 11 BeforeNode 7 success
10 9 8 11 7 6 5 4 3 2 1 first:10 last:1 
insert 12 BeforeNode 8 success
10 9 12 8 11 7 6 5 4 3 2 1 first:10 last:1 
insert 13 BeforeNode 10 success
13 10 9 12 8 11 7 6 5 4 3 2 1 first:13 last:1 
insert 14 BeforeNode 10 success
13 14 10 9 12 8 11 7 6 5 4 3 2 1 first:13 last:1 
insert 15 BeforeNode 2 success
13 14 10 9 12 8 11 7 6 5 4 3 15 2 1 first:13 last:1 
insert 16 BeforeNode 4 success
13 14 10 9 12 8 11 7 6 5 16 4 3 15 2 1 first:13 last:1 
insert 17 BeforeNode 12 success
13 14 10 9 17 12 8 11 7 6 5 16 4 3 15 2 1 first:13 last:1 
insert 18 BeforeNode 7 success
13 14 10 9 17 12 8 11 18 7 6 5 16 4 3 15 2 1 first:13 last:1 
insert 19 BeforeNode 15 success
13 14 10 9 17 12 8 11 18 7 6 5 16 4 3 19 15 2 1 first:13 last:1 
insert 20 BeforeNode 9 success
13 14 10 20 9 17 12 8 11 18 7 6 5 16 4 3 19 15 2 1 first:13 last:1 

Test removeNode function
removeNode success:1
13 14 10 20 9 17 12 8 11 18 7 6 5 16 4 3 19 15 2 first:13 last:2 
removeNode success:2
13 14 10 20 9 17 12 8 11 18 7 6 5 16 4 3 19 15 first:13 last:15 
removeNode success:3
13 14 10 20 9 17 12 8 11 18 7 6 5 16 4 19 15 first:13 last:15 
removeNode success:4
13 14 10 20 9 17 12 8 11 18 7 6 5 16 19 15 first:13 last:15 
removeNode success:5
13 14 10 20 9 17 12 8 11 18 7 6 16 19 15 first:13 last:15 
removeNode success:6
13 14 10 20 9 17 12 8 11 18 7 16 19 15 first:13 last:15 
removeNode success:7
13 14 10 20 9 17 12 8 11 18 16 19 15 first:13 last:15 
removeNode success:8
13 14 10 20 9 17 12 11 18 16 19 15 first:13 last:15 
removeNode success:9
13 14 10 20 17 12 11 18 16 19 15 first:13 last:15 
removeNode success:10
13 14 20 17 12 11 18 16 19 15 first:13 last:15 
removeNode success:11
13 14 20 17 12 18 16 19 15 first:13 last:15 
removeNode success:12
13 14 20 17 18 16 19 15 first:13 last:15 
removeNode success:13
14 20 17 18 16 19 15 first:14 last:15 
removeNode success:14
20 17 18 16 19 15 first:20 last:15 
removeNode success:15
20 17 18 16 19 first:20 last:19 
removeNode success:16
20 17 18 19 first:20 last:19 
removeNode success:17
20 18 19 first:20 last:19 
removeNode success:18
20 19 first:20 last:19 
removeNode success:19
20 first:20 last:20 
removeNode success:20
first:null last:null 

Test insertAfterNode function
Initial list:
10 9 8 7 6 5 4 3 2 1 first:10 last:1 
insert 11 AfterNode 10 success
10 11 9 8 7 6 5 4 3 2 1 first:10 last:1 
insert 12 AfterNode 9 success
10 11 9 12 8 7 6 5 4 3 2 1 first:10 last:1 
insert 13 AfterNode 8 success
10 11 9 12 8 13 7 6 5 4 3 2 1 first:10 last:1 
insert 14 AfterNode 10 success
10 14 11 9 12 8 13 7 6 5 4 3 2 1 first:10 last:1 
insert 15 AfterNode 10 success
10 15 14 11 9 12 8 13 7 6 5 4 3 2 1 first:10 last:1 
insert 16 AfterNode 4 success
10 15 14 11 9 12 8 13 7 6 5 4 16 3 2 1 first:10 last:1 
insert 17 AfterNode 8 success
10 15 14 11 9 12 8 17 13 7 6 5 4 16 3 2 1 first:10 last:1 
insert 18 AfterNode 11 success
10 15 14 11 18 9 12 8 17 13 7 6 5 4 16 3 2 1 first:10 last:1 
insert 19 AfterNode 14 success
10 15 14 19 11 18 9 12 8 17 13 7 6 5 4 16 3 2 1 first:10 last:1 
insert 20 AfterNode 3 success
10 15 14 19 11 18 9 12 8 17 13 7 6 5 4 16 3 20 2 1 first:10 last:1 
原文地址:https://www.cnblogs.com/songdechiu/p/6518373.html