簡體   English   中英

使用交換方法反轉泛型 LinkedList

[英]Reverse generic LinkedList by using swap method

        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));
    }
  }

使用交換方法反轉通用 LinkedList 的最佳方法是什么? 在反向方法之前:

(head=[9])->[8]->[7]->[6]->[5]->[4]->[3]->[2]->[1]->[ 0]-> 空

在 reverse() 方法之后:

(head=[0])->[1]->[2]->[3]->[4]->[5]->[6]->[7]->[8]->[ 9]-> 空

您需要做的是將列表分成兩半。 如果列表大小為奇數,則中間的將保留在原位。 然后像時尚一樣在鏡子中交換兩側的元素。 這應該比 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 的檢查。 一個 for 循環。 時間復雜度 O(n)。 還需要檢查size=2的時候,直接調用swap(...)。

基於@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));
            }
        }

反轉LinkedList。

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM