使用交换方法反转通用LinkedList

时间:2017-01-10 15:52:08

标签: java algorithm generics linked-list

        public class SimpleLinkedList<E> {

            public Node<E> head;

            public int size;

            public void add(E e) {
                ++this.size;
                if (null == head) {
                    this.head = new Node();
                    head.val = e;
                } else {
                    Node<E> newNode = new Node();
                    newNode.val = e;
                    newNode.next = head;
                    this.head = newNode;
                }
            }

public void swap(E val1, E val2) {
        if (val1.equals(val2)) {
            return;
        }
        Node prevX = null, curr1 = head;
        while (curr1 != null && !curr1.val.equals(val1)) {
            prevX = curr1;
            curr1 = curr1.next;
        }
        Node prevY = null, curr2 = head;
        while (curr2 != null && !curr2.val.equals(val2)) {
            prevY = curr2;
            curr2 = curr2.next;
        }
        if (curr1 == null || curr2 == null) {
            return;
        }
        if (prevX == null) {
            head = curr2;
        } else {
            prevX.next = curr2;
        }
        if (prevY == null) {
            head = curr1;
        } else {
            prevY.next = curr1;
        }
        Node temp = curr1.next;
        curr1.next = curr2.next;
        curr2.next = temp;
    }

       public void reverse() {
            Node<E> prev = null;
            Node<E> current = head;
            Node<E> next = null;
            while (current != null) {
                next = current.next;
                current.next = prev;
                prev = current;
                current = next;
            }
            head = prev;
        }


        public static class Node<E> {
            public Node<E> next;
            public E val;
        }
    }


    public class SimpleLinkedListTest {

      @Test
    public void testReverseMethod() {
        SimpleLinkedList<Integer> myList = new SimpleLinkedList<>();
        for (int i = 0; i < 10; i++) {
            myList.add(i);
        }
        SimpleLinkedList<Integer> expectedList = new SimpleLinkedList<>();
        for (int i = 9; i > -1; i--) {
            expectedList.add(i);
        }
        myList.reverse();
        assertTrue(AssertCustom.assertSLLEquals(expectedList, myList));
    }
  }

使用swap方法反转泛型LinkedList的最佳方法是什么? 在反向方法之前:

(头= [9]) - &GT; [8] - &GT; [7] - &GT; [6] - &GT; [5] - &GT; [4] - &GT; [3] - &GT; [ 2] - &GT; [1] - &GT; [0] - &GT;空

在reverse()方法之后:

(头= [0]) - &GT; [1] - &GT; [2] - &GT; [3] - &GT; [4] - &GT; [5] - &GT; [6] - &GT; [ 7] - GT; [8] - &GT; [9] - &GT;空

3 个答案:

答案 0 :(得分:1)

您需要做的是将列表分成两半。如果列表大小为奇数,则中间的大小将保持不变。然后像时尚一样在镜子的两边交换元素。这应该比O(n ^ 2)

更有效
reverse(){
    Node current = this.head;
    int half = this.size/2;
    int midElement = this.size % 2 == 0 ? 0: half + 1;
    Stack<Node<E>> stack = new Stack<Node<E>>();

    for(int i = 0; i < this.size; i++){
        if (i < = half)
            stack.push(current);
        else{
            if (i == midElement)
                continue;
            else
                swap(stack.pop(), current);
        current = current.next;
    }
}

swap(Node<E> v, Node<E> v1){
    E tmp = v.value;
    v.value = v1.value;
    v1.value = tmp;
}

这是一些伪java。当它应该立即返回时,它仍然缺少size = 0或size = 1的检查。一个循环。时间复杂度O(n)。还需要检查size = 2,直接调用swap(...)。

答案 1 :(得分:0)

根据@efekctive的想法,有一个解决方案。复杂性比O ^ 2稍差,但不需要更改交换方法,不需要使用其他集合。下面的代码通过了单元测试,但是,请小心使用它可能存在与size / 2操作相关的错误。希望这有帮助。

 public void reverse() {
            Node<E> current = head;
            SimpleLinkedList<E> firstHalf = new SimpleLinkedList<>();
            SimpleLinkedList<E> secondHalf = new SimpleLinkedList<>();
            for (int i = 0; i < size; i++) {
                if (i >= size / 2) {
                    firstHalf.add(current.val);
                } else {
                    secondHalf.add(current.val);
                }
                current = current.next;
            }
            SimpleLinkedList<E> secondHalfReverse = new SimpleLinkedList<>();
            for (int i = 0; i < secondHalf.size(); i++) {
                secondHalfReverse.add(secondHalf.get(i));
            }
            for (int i = 0; i < size / 2; i++) {
                if (secondHalfReverse.get(i) == firstHalf.get(i)) {
                    break;
                }
                swap(secondHalfReverse.get(i), firstHalf.get(i));
            }
        }

答案 2 :(得分:-1)

反向链接列表。

private Node reverse(Node num) {
    Node currentnode = num;
    Node reverseNode = null;
    while(currentnode!=null){
        Node temp = currentnode;
        currentnode = currentnode.next;
        temp.next = reverseNode;
        reverseNode = temp;
    }
    return reverseNode;
}