Java双向链表倒置功能实现-(阿里巴巴招聘课题)

题目要求:
实现一个双向链表的倒置功能(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


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值