双链表 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());
}
}