单链表 SinglyLinkedList
创建实现类并实现方法
package com. lhs ;
public class SinglyLinkedList < E > implements List < E > {
private Node < E > first;
private Node < E > last;
private int size;
public static class Node < E > {
E data;
Node < E > next;
Node ( E data, Node < E > next) {
this . data = data;
this . next = next;
}
}
@Override
public int size ( ) {
return size;
}
@Override
public boolean isEmpty ( ) {
return size == 0 ;
}
@Override
public boolean contains ( Object o) {
if ( o == null ) {
for ( Node < E > node = first; node != null ; node = node. next) {
if ( node. data == null ) {
return true ;
}
}
return false ;
} else {
for ( Node < E > node = first; node != null ; node = node. next) {
if ( o. equals ( node. data) ) {
return true ;
}
}
}
return false ;
}
@Override
public boolean add ( E e) {
Node < E > l = last;
Node < E > eNode = new Node < > ( e, null ) ;
if ( l != null ) {
l. next = eNode;
} else {
first = eNode;
}
last = eNode;
size++ ;
return true ;
}
@Override
public E get ( int index) {
if ( index >= size || index < 0 ) {
throw new IndexOutOfBoundsException ( index + "is out of bounds" ) ;
}
Node < E > node = first;
for ( int i = 0 ; i < index; i++ ) {
node = node. next;
}
return node. data;
}
@Override
public E set ( int index, E e) {
if ( index >= size || index < 0 ) {
throw new IndexOutOfBoundsException ( index + "is out of bounds" ) ;
}
Node < E > node = first;
for ( int i = 0 ; i < index; i++ ) {
node = node. next;
}
E oldVal = node. data;
node. data = e;
return oldVal;
}
@Override
public E remove ( int index) {
if ( index >= size || index < 0 ) {
throw new IndexOutOfBoundsException ( index + "is out of bounds" ) ;
}
Node < E > node = first;
Node < E > before = null ;
E oldVal;
if ( index == 0 ) {
oldVal = first. data;
first = first. next;
} else {
for ( int i = 0 ; i < index; i++ ) {
if ( i == index - 1 ) {
before = node;
}
node = node. next;
}
oldVal = node. data;
before. next = node. next;
}
size-- ;
return oldVal;
}
@Override
public void addFirst ( E e) {
Node < E > oldVal = first;
Node < E > eNode = new Node < > ( e, oldVal) ;
first = eNode;
size++ ;
}
@Override
public void addLast ( E e) {
add ( e) ;
}
@Override
public E removeFirst ( ) {
return remove ( 0 ) ;
}
@Override
public E removeLast ( ) {
return remove ( size) ;
}
}
测试
package com. lhs ;
import org. junit. Test ;
import static junit. framework. TestCase . * ;
import static org. junit. Assert . assertThrows ;
public class SinglyLinkedListTest {
@Test
public void testSize ( ) {
List < String > list = new SinglyLinkedList < String > ( ) ;
assertTrue ( list. size ( ) == 0 ) ;
list. add ( "Java" ) ;
assertTrue ( list. size ( ) == 1 ) ;
}
@Test
public void testIsEmpty ( ) {
List < String > list = new SinglyLinkedList < String > ( ) ;
assertTrue ( list. isEmpty ( ) ) ;
list. add ( "Java" ) ;
assertFalse ( list. isEmpty ( ) ) ;
}
@Test
public void testContains ( ) {
List < String > list = new SinglyLinkedList < 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 SinglyLinkedList < 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 SinglyLinkedList < 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) ;
} ) ;
assertEquals ( index + "is out of bounds" ,
excpetion. getMessage ( ) ) ;
}
@Test
public void testSet ( ) {
List < String > list = new SinglyLinkedList < 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" ) ;
} ) ;
assertEquals ( index + "is out of bounds" ,
excpetion. getMessage ( ) ) ;
}
@Test
public void testRemove ( ) {
List < String > list = new SinglyLinkedList < String > ( ) ;
list. add ( "Java" ) ;
list. add ( "C++" ) ;
list. add ( "C" ) ;
assertEquals ( "C" , list. remove ( 2 ) ) ;
assertEquals ( "Java" , list. get ( 0 ) ) ;
assertEquals ( "C++" , list. get ( 1 ) ) ;
int index = 6 ;
Throwable excpetion = assertThrows (
IndexOutOfBoundsException . class , ( ) -> {
list. remove ( index) ;
} ) ;
assertEquals ( index + "is out of bounds" ,
excpetion. getMessage ( ) ) ;
}
@Test
public void testAddFirst ( ) {
List < String > list = new SinglyLinkedList < 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 ( ) {
List < String > list = new SinglyLinkedList < 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 ( ) {
List < String > list = new SinglyLinkedList < 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 ( ) {
List < String > list = new SinglyLinkedList < String > ( ) ;
list. add ( "Java" ) ;
list. add ( "C++" ) ;
list. add ( "C" ) ;
assertEquals ( "C" , list. removeLast ( ) ) ;
assertEquals ( "C++" , list. removeLast ( ) ) ;
assertEquals ( "Java" , list. removeLast ( ) ) ;
}
}