双向链表实现:
//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
来源:oschina
链接:https://my.oschina.net/u/4342102/blog/3220136