簡體   English   中英

反向鏈接列表

[英]Reversing a linked-list

我正在編寫一個簡單的遞歸代碼來反轉Java中的鏈表。 奇怪的是,它返回了相同的節點。

Node reverse(Node ptr) {
    if (ptr.link == null)
        return ptr;

    Node second = ptr.link;
    ptr.link = null;

    Node rest = reverse(second);
    rest.link = ptr;

    return rest;
}

為什么這不起作用?

您當前的方法行不通,從遞歸調用返回的rest值不指向列表中的最后一個元素(應該是節點的插入點),而是指向該對象的第一個元素。結果。 換句話說,此行未正確構建輸出:

rest.link = ptr;

為了成功地反轉列表,一種策略是使用累加器參數,因此我們可以在遞歸展開時將其插入列表的開頭-請記住,遞歸相對於元素開始以相反的順序“返回”在列表中。 試試這個,這是一個尾遞歸解決方案:

Node reverse(Node ptr, Node acc) {
    if (ptr == null)
        return acc;
    Node second = ptr.link;
    ptr.link = acc;
    return reverse(second, ptr);
}

像這樣調用上面的方法:

Node reversedList = reverse(list, null);

請注意,輸入list 被就地修改,並且在方法返回后將不會相同,任何保存對list的引用的變量都會受到影響。 如果這是一個問題,則應在將list傳遞給reverse()之前創建list的副本。

Oscar是正確的,即遞歸調用的返回值不指向最后一個元素。

還有另一種不使用累加器參數的算法:

function reverse(node) {
  if (node.next == null)
    return node;
  var tail = reverse(node.next);
  node.next.next = node;
  node.next = null;
  return tail;
}
Node reverseNode(Node node){
Node head = null;
While(node.next != null){
    Node n = new Node(node.data);
    n.next = head;
    head = n;
    node = node.next;
}
return head;}

您知道您不必編寫遞歸函數

暫無
暫無

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

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