题目要求:
实现一个双向链表的倒置功能(1->2->3 变成 3->2->1)
时间:3天之内即可
提交:代码、测试用例(单元测试)
实现一个双向链表的倒置功能(1->2->3 变成 3->2->1)
时间:3天之内即可
提交:代码、测试用例(单元测试)
请认真审题,请勿直接使用JDK的LinkedList。完成一个完整的可运行的Java工程,包含单元测试。
链表实现:
package com.alibaba.job; import java.util.*; /** * 阿里巴巴招聘题目:双向链表倒置功能实现 * @author hongyan.wang * @Email why000007@163.com * @Date 04/18/2018 * @param <E> 集合中保存的元素类型 */ public class DoubleLinkedList<E> { transient Node<E> first; transient Node<E> last; transient int size = 0; private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } /** * 构造一个空列表. */ public DoubleLinkedList() { } /** * 返回列表中的元素个数. */ public int size() { return size; } /** * 将指定的元素追加到列表的末尾. * @param e element to be appended to this list */ public void add(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; } /** * 返回列表中指定位置的元素 * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException */ public E get(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException(String.format("Index out of bound %d", index)); if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x.item; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x.item; } } /** * 颠倒指定列表中的元素的顺序 */ public void reverse() { if(first == null || first.next == null) { return; } Node<E> temp = first; first = last; last = temp; Node<E> node = first; while(node != null) { temp = node.next; node.next = node.prev; node.prev = temp; node = node.next; } } /** * 从列表中删除所有的元素. */ public void clear() { for (Node<E> x = first; x != null; ) { Node<E> next = x.next; x.item = null; x.next = null; x.prev = null; x = next; } first = last = null; size = 0; } /** * 返回包含列表中所有元素的序列数组 */ public Object[] toArray() { Object[] result = new Object[size]; int i = 0; for (Node<E> x = first; x != null; x = x.next) result[i++] = x.item; return result; } /** * 返回列表中元素的列表迭代器 * @throws NoSuchElementException * @throws IllegalStateException * @throws RuntimeException */ public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor = 0; int lastRet = -1; public boolean hasNext() { return cursor != size(); } public E next() { try { E next = get(cursor); lastRet = cursor++; return next; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } @Override public void remove() { if (lastRet == -1) throw new IllegalStateException(); throw new RuntimeException("remove is denied"); } } }
测试用例:
package com.alibaba.job; import java.io.PrintStream; import java.util.Iterator; /** * 阿里巴巴招聘题目:双向链表倒置功能测试用例 * @author hongyan.wang * @Email why000007@163.com * @Date 04/18/2018 */ public class TestCase { /** * 双向链表倒置测试主函数 * 执行顺序:初始化->打印列表元素->链表倒置->打印列表元素 * @param args */ public static void main(String[] args) { //初始化双向链表1,2,3 DoubleLinkedList<Integer> dlist = new DoubleLinkedList<Integer>() {{ add(1); add(2); add(3); }}; // DoubleLinkedList<Integer> dlist = new DoubleLinkedList<>() // for(int i=1; i<=3; i++ ) { // dlist.add(i); // } //倒置前输出控制台 print("双向链表倒置前: ", dlist, System.out); //倒置双向链表 dlist.reverse(); //倒置后输出控制台 print("双向链表倒置后: ", dlist, System.out); } /** * 打印输出双向链表元素 * @param desc 打印说明 * @param plist 双向链表 * @param out 输出定向 */ public static void print(String desc, DoubleLinkedList plist, PrintStream out) { StringBuilder sb = new StringBuilder(desc); Iterator<Integer> it = plist.iterator(); while(it.hasNext()) { sb.append(String.format("%s ", it.next())); } out.println(sb.toString()); } }
测试结果:
"D:\Program Files\Java\jdk1.8.0_101\bin\java" com.intellij.rt.execution.application.AppMain com.alibaba.job.TestCase
双向链表倒置前: 1 2 3
双向链表倒置后: 3 2 1
Process finished with exit code 0