[英]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.