问题描述
修改Node类实现双端链表
难点分析:
提示:这里不仅要改Node类还要去改迭代器,其他的可用实现,但是测试测试程序并没有要求:
首先是Node类的一些改动,主要是加了一个previous,这个值为了向前遍历
其次就是时刻注意size这个数据域
最后当链表加的元素是第一个的时候一定要注意,这个时候previous指向的是空。
代码:
提示:其实这几个结构的实现都没有怎么考虑极端情况,也就是异常处理,可以考虑一手:
/* You have to use the following template to submit to Revel.
Note: To test the code using the CheckExerciseTool, you will submit entire code.
To submit your code to Revel, you must only submit the code enclosed between
// BEGIN REVEL SUBMISSION
// END REVEL SUBMISSION
*/
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Scanner;
import java.util.Collection;
public class Lab24_3 {
public static void main(String[] args) {
new Lab24_3();
}
public Lab24_3() {
TwoWayLinkedList<Double> list = new TwoWayLinkedList<>();
System.out.print("Enter five numbers: ");
Scanner input = new Scanner(System.in);
double[] v = new double[5];
for (int i = 0; i < 5; i++)
v[i] = input.nextDouble();
list.add(v[1]);
list.add(v[2]);
list.add(v[3]);
list.add(v[4]);
list.add(0, v[0]);
list.add(2, 10.55);
list.remove(3);
java.util.ListIterator<Double> iterator1 = list.listIterator();
System.out.println("向下遍历");
while (iterator1.hasNext())
System.out.print(iterator1.next() + " ");
java.util.ListIterator<Double> iterator2 = list.listIterator(list.size() - 1);
System.out.println();
System.out.println("向上遍历");
while (iterator2.hasPrevious())
System.out.print(iterator2.previous() + " ");
}
}
interface MyList1<E> extends java.util.Collection<E> {
/**
* Add a new element at the specified index in this list
*/
public void add(int index, E e);
/**
* Return the element from this list at the specified index
*/
public E get(int index);
/**
* Return the index of the first matching element in this list.
* Return -1 if no match.
*/
public int indexOf(Object e);
/**
* Return the index of the last matching element in this list
* Return -1 if no match.
*/
public int lastIndexOf(E e);
/**
* Remove the element at the specified position in this list
* Shift any subsequent elements to the left.
* Return the element that was removed from the list.
*/
public E remove(int index);
/**
* Replace the element at the specified position in this list
* with the specified element and returns the new set.
*/
public E set(int index, E e);
@Override
/** Add a new element at the end of this list */
public default boolean add(E e) {
add(size(), e);
return true;
}
@Override
/** Return true if this list contains no elements */
public default boolean isEmpty() {
return size() == 0;
}
@Override
/** Remove the first occurrence of the element e
* from this list. Shift any subsequent elements to the left.
* Return true if the element is removed. */
public default boolean remove(Object e) {
if (indexOf(e) >= 0) {
remove(indexOf(e));
return true;
} else
return false;
}
@Override
public default boolean containsAll(Collection<?> c) {
// Left as an exercise
return true;
}
@Override
public default boolean addAll(Collection<? extends E> c) {
// Left as an exercise
return true;
}
@Override
public default boolean removeAll(Collection<?> c) {
// Left as an exercise
return true;
}
@Override
public default boolean retainAll(Collection<?> c) {
// Left as an exercise
return true;
}
@Override
public default Object[] toArray() {
// Left as an exercise
return null;
}
@Override
public default <T> T[] toArray(T[] array) {
// Left as an exercise
return null;
}
}
class TwoWayLinkedList<E> implements MyList1<E> {
private Node<E> head, tail;
private int size;
/**
* Create a default list
*/
public TwoWayLinkedList() {
}
/**
* Create a list from an array of objects
*/
public TwoWayLinkedList(E[] objects) {
for (E e : objects)
add(e);
}
/**
* Return the head element in the list
*/
public E getFirst() {
if (size == 0) {
return null;
} else {
return head.element;
}
}
/**
* Return the last element in the list
*/
public E getLast() {
if (size == 0) {
return null;
} else {
return tail.element;
}
}
@Override
public String toString() {
StringBuilder result = new StringBuilder("[");
Node<E> current = head;
for (int i = 0; i < size; i++) {
result.append(current.element);
current = current.next;
if (current != null) {
result.append(", "); // Separate two elements with a comma
} else {
result.append("]"); // Insert the closing ] in the string
}
}
return result.toString();
}
/**
* Clear the list
*/
public void clear() {
head = tail = null;
}
/**
* Return true if this list contains the element o
*/
public boolean contains(Object e) {
System.out.println("Implementation left as an exercise");
return true;
}
/**
* Return the element from this list at the specified index
*/
public E get(int index) {
System.out.println("Implementation left as an exercise");
return null;
}
/**
* Return the index of the head matching element in this list. Return -1 if
* no match.
*/
public int indexOf(Object e) {
System.out.println("Implementation left as an exercise");
return 0;
}
/**
* Return the index of the last matching element in this list Return -1 if
* no match.
*/
public int lastIndexOf(Object e) {
System.out.println("Implementation left as an exercise");
return 0;
}
/**
* Replace the element at the specified position in this list with the
* specified element.
*/
public E set(int index, E e) {
System.out.println("Implementation left as an exercise");
return null;
}
private class LinkedListIterator implements java.util.ListIterator<E> {
private Node<E> current = head; // Current index
public LinkedListIterator() {
}
public LinkedListIterator(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
+ size);
for (int nextIndex = 0; nextIndex < index; nextIndex++)
current = current.next;
}
public void setLast() {
current = tail;
}
@Override
public boolean hasNext() {
return (current != null);
}
@Override
public E next() {
E e = current.element;
current = current.next;
return e;
}
@Override
public void remove() {
System.out.println("Implementation left as an exercise");
}
@Override
public void add(E e) {
System.out.println("Implementation left as an exercise");
}
@Override
public boolean hasPrevious() {
return current != null;
}
@Override
public int nextIndex() {
System.out.println("Implementation left as an exercise");
return 0;
}
@Override
public E previous() {
E e = current.element;
current = current.previous;
return e;
}
@Override
public int previousIndex() {
System.out.println("Implementation left as an exercise");
return 0;
}
@Override
public void set(E e) {
current.element = e; // TODO Auto-generated method stub
}
}
private class Node<E> {
E element;
Node<E> next;
Node<E> previous;
public Node(E o) {
element = o;
}
}
@Override
public int size() {
return size;
}
public ListIterator<E> listIterator() {
return new LinkedListIterator();
}
public ListIterator<E> listIterator(int index) {
return new LinkedListIterator(index);
}
@Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return null;
}
// BEGIN REVEL SUBMISSION
/**
* Add an element to the beginning of the list
*/
public void addFirst(E e) {
Node<E> newNode = new Node<>(e);
newNode.next = head;
//如果链表中一个元素都没有
if (size == 0) {
head = newNode;
size++;
} else {
head.previous = newNode;
head = newNode;
size++;
}
if (tail == null)
tail = head;
}
/**
* Add an element to the end of the list
*/
public void addLast(E e) {
Node<E> newNode = new Node<>(e);
if (tail == null)
head = tail = newNode;
else {
tail.next = newNode;
newNode.previous = tail;
tail = newNode;
}
size++;
}
/**
* Add a new element at the specified index in this list The index of the
* head element is 0
*/
public void add(int index, E e) {
Node<E> current = head;
if (index == 0) {
addFirst(e);
} else if (index >= size) {
addLast(e);
} else {
for (int i = 1; i < index; i++)
current = current.next;
Node<E> temp = current.next;
current.next = new Node<>(e);
temp.previous = current.next;
//将其链接起来
current.next.next = temp;
temp.previous.previous = current;
//长度
size++;
}
}
/**
* Remove the head node and return the object that is contained in the
* removed node.
*/
public E removeFirst() {
if (size == 0) {
return null;
} else {
Node<E> temp = head;
head = head.next;
head.previous = null;
size--;
//考虑到只有一个元素的情况
if (head == null) {
tail = null;
}
return temp.element;
}
}
/**
* Remove the last node and return the object that is contained in the
* removed node.
*/
public E removeLast() {
if (size == 0)
return null;
else if (size == 1) {
Node<E> temp = head;
head = tail = null;
size = 0;
return temp.element;
} else {
Node<E> temp = tail;
tail = tail.previous;
tail.next = null;
size--;
return temp.element;
}
}
/**
* Remove the element at the specified position in this list. Return the
* element that was removed from the list.
*/
public E remove(int index) {
if (index < 0 || index >= size)
return null;
else if (index == 0)
return removeFirst();
else if (index == size - 1)
return removeLast();
else {
Node<E> current = head;
for (int i = 0; i < index; i++)
current = current.next;
current.previous.next = current.next;
current.next.previous = current.previous;
size--;
return current.element;
}
}
}
// END REVEL SUBMISSION