双链表 LinkedList
实现代码
package com. lhs ; public class LinkedList < E > implements List < E > { private int size; private Node < E > first; private Node < E > last; public static class Node < E > { E data; Node < E > next; Node < E > pre; Node ( E data, Node < E > next, Node < E > pre) { this . data = data; this . next = next; this . pre = pre; } } @Override public int size ( ) { return size; } @Override public boolean isEmpty ( ) { return size == 0 ; } @Override public boolean contains ( Object o) { return IndexOf ( o) >= 0 ; } public int IndexOf ( Object o) { Node < E > node = first; if ( o == null ) { for ( int i = 0 ; i < size; i++ ) { if ( node. data == null ) { return i; } node = node. next; } return - 1 ; } else { for ( int i = 0 ; i < size; i++ ) { if ( o. equals ( node. data) ) { return i; } node = node. next; } return - 1 ; } } @Override public boolean add ( E e) { if ( size == 0 ) { Node < E > node = new Node < > ( e, null , null ) ; first = node; last = node; } else { Node < E > l = last; Node < E > node = new Node < > ( e, null , l) ; l. next = node; last = node; } size++ ; return true ; } @Override public E get ( int index) { if ( index >= size) { throw new IndexOutOfBoundsException ( index + " out of bound" ) ; } Node < E > node; if ( index > ( size >> 1 ) ) { node = last; for ( int i = 0 ; i< size - index - 1 ; i++ ) { node = node. pre; } } else { node = first; for ( int i = 0 ; i < size - index - 1 ; i++ ) { node = node. next; } } return node. data; } @Override public E set ( int index, E e) { if ( index >= size) { throw new IndexOutOfBoundsException ( index + " out of bound" ) ; } E oldVal; Node < E > node; if ( index > ( size >> 1 ) ) { node = last; for ( int i = 0 ; i< size - index - 1 ; i++ ) { node = node. pre; } } else { node = first; for ( int i = 0 ; i < size - index - 1 ; i++ ) { node = node. next; } } oldVal = node. data; node . data = e; return oldVal; } @Override public E remove ( int index) { if ( index >= size) { throw new IndexOutOfBoundsException ( index + " out of bound" ) ; } Node < E > node; if ( index > ( size >> 1 ) ) { node = last; for ( int i = 0 ; i< size - index - 1 ; i++ ) { node = node. pre; } } else { node = first; for ( int i = 0 ; i < size - index - 1 ; i++ ) { node = node. next; } } E oldVal = node. data; Node < E > n = node. next; Node < E > p = node. pre; if ( p != null ) { p. next = n; } else { first = n; } if ( n != null ) { n. pre = p; } else { last = p; } size-- ; return oldVal; } @Override public void addFirst ( E e) { Node < E > f = first; Node < E > node = new Node < > ( e, null , f) ; f. pre = node; first = node; size++ ; } @Override public void addLast ( E e) { add ( e) ; } @Override public E removeFirst ( ) { return remove ( 0 ) ; } @Override public E removeLast ( ) { return remove ( size- 1 ) ; }
}
测试代码
package com. lhs ; import org. junit. Test ; import java. util. LinkedList ;
import java. util. List ; import static junit. framework. TestCase . * ;
import static org. junit. Assert . assertThrows ;
public class LinkedListTests { @Test public void testSize ( ) { List < String > list = new LinkedList < String > ( ) ; assertTrue ( list. size ( ) == 0 ) ; list. add ( "Java" ) ; assertTrue ( list. size ( ) == 1 ) ; } @Test public void testIsEmpty ( ) { List < String > list = new LinkedList < String > ( ) ; assertTrue ( list. isEmpty ( ) ) ; list. add ( "Java" ) ; assertFalse ( list. isEmpty ( ) ) ; } @Test public void testContains ( ) { List < String > list = new LinkedList < String > ( ) ; list. add ( "Java" ) ; list. add ( "C++" ) ; list. add ( "C" ) ; list. add ( "Python" ) ; list. add ( "TypeScript" ) ; assertTrue ( list. contains ( "Java" ) ) ; assertFalse ( list. contains ( "Java++" ) ) ; } @Test public void testAdd ( ) { List < Integer > list = new LinkedList < Integer > ( ) ; list. add ( 1 ) ; list. add ( 2 ) ; list. add ( 3 ) ; list. add ( 4 ) ; list. add ( 5 ) ; assertFalse ( list. isEmpty ( ) ) ; } @Test public void testGet ( ) { List < String > list = new LinkedList < String > ( ) ; list. add ( "Java" ) ; list. add ( "C++" ) ; list. add ( "C" ) ; assertEquals ( "C++" , list. get ( 1 ) ) ; int index = 6 ; Throwable excpetion = assertThrows ( IndexOutOfBoundsException . class , ( ) -> { list. get ( index) ; } ) ; assertNotNull ( excpetion. getMessage ( ) ) ; } @Test public void testSet ( ) { List < String > list = new LinkedList < String > ( ) ; list. add ( "Java" ) ; list. add ( "C++" ) ; list. add ( "C" ) ; assertEquals ( "C" , list. set ( 2 , "Python" ) ) ; int index = 6 ; Throwable excpetion = assertThrows ( IndexOutOfBoundsException . class , ( ) -> { list. set ( index, "Python" ) ; } ) ; assertNotNull ( excpetion. getMessage ( ) ) ; } @Test public void testRemove ( ) { List < String > list = new LinkedList < String > ( ) ; list. add ( "Java" ) ; list. add ( "C++" ) ; list. add ( "C" ) ; assertEquals ( "C" , list. remove ( 2 ) ) ; assertEquals ( "C++" , list. remove ( 1 ) ) ; assertEquals ( "Java" , list. get ( 0 ) ) ; int index = 6 ; Throwable excpetion = assertThrows ( IndexOutOfBoundsException . class , ( ) -> { list. remove ( index) ; } ) ; assertNotNull ( excpetion. getMessage ( ) ) ; } @Test public void testAddFirst ( ) { LinkedList < String > list = new LinkedList < String > ( ) ; list. addFirst ( "Java" ) ; list. addFirst ( "C++" ) ; list. addFirst ( "C" ) ; assertEquals ( "C" , list. get ( 0 ) ) ; assertEquals ( "C++" , list. get ( 1 ) ) ; assertEquals ( "Java" , list. get ( 2 ) ) ; } @Test public void testAddLast ( ) { LinkedList < String > list = new LinkedList < String > ( ) ; list. addLast ( "Java" ) ; list. addLast ( "C++" ) ; list. addLast ( "C" ) ; assertEquals ( "Java" , list. get ( 0 ) ) ; assertEquals ( "C++" , list. get ( 1 ) ) ; assertEquals ( "C" , list. get ( 2 ) ) ; } @Test public void testRemoveFirst ( ) { LinkedList < String > list = new LinkedList < String > ( ) ; list. add ( "Java" ) ; list. add ( "C++" ) ; list. add ( "C" ) ; assertEquals ( "Java" , list. removeFirst ( ) ) ; assertEquals ( "C++" , list. removeFirst ( ) ) ; assertEquals ( "C" , list. removeFirst ( ) ) ; } @Test public void testRemoveLast ( ) { LinkedList < String > list = new LinkedList < String > ( ) ; list. add ( "Java" ) ; list. add ( "C++" ) ; list. add ( "C" ) ; assertEquals ( "C" , list. removeLast ( ) ) ; assertEquals ( "C++" , list. removeLast ( ) ) ; assertEquals ( "Java" , list. removeLast ( ) ) ; } }