亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

編譯器不會推進單鏈表的遞歸反轉

編譯器不會推進單鏈表的遞歸反轉

侃侃爾雅 2023-06-21 15:37:28
我在一個類中有一個遞歸靜態方法SinglyLinkedList,該方法由于不確定的原因而永遠運行。這個類是通用的,它的聲明如下:public class SinglyLinkedList<E>{這個類有一個內部泛型類Node,如下所示:private static class Node<E> {    private E element;    private Node<E> next;    public Node(E e, Node<E> n) {        this.element = e;        this.next = n;    }    public E getElement() {        return this.element;    }    public Node<E> getNext() {        return this.next;    }    public void setNext(Node<E> n) {        this.next = n;    }}此外,該類SinglyLinkedList還有以下字段:private Node<E> head = null;private Node<E> tail = null;private int size = 0;我遇到問題的方法被調用reverse,其目的是以遞歸方式反轉單鏈表的順序。這是此方法的代碼:public static SinglyLinkedList reverse(SinglyLinkedList l) {    if (l.size < 2) return l;    Node first = l.removeFirstNode();    SinglyLinkedList reversed = reverse(l);    reversed.addLast(first);    return reversed;}該reverse方法使用一個非靜態方法調用,removeFirstNode其目的是刪除Node單鏈表中的第一個并返回它:private Node<E> removeFirstNode() {    if (isEmpty()) return null;    //Node<E> answer = new Node<>(this.head.getElement(), null);    Node<E> answer = this.head;    this.head = this.head.getNext();    this.size--;    if (this.size == 0) this.tail = null;    return answer;}該reverse方法還使用一個非靜態方法調用,addLast其目的是將給定添加Node到單鏈表的末尾:private void addLast(Node<E> n) {    if (isEmpty()) this.head = n;    else this.tail.setNext(n);    this.tail = n;    this.size++;}問題是,當我嘗試在等于 2 的a上運行該reverse方法時,編譯器到達該行SinglyLinkedListsizereversed.addLast(first);然后在addLast方法內部它停在線上this.tail = n;并永遠運行而不終止。如果size等于 3 或更多,編譯器將到達該行reversed.addLast(first);甚至沒有進入方法就停在那里addLast。現在如果我更換線路Node<E> answer = this.head;與當前注釋掉的行Node<E> answer = new Node<>(this.head.getElement(), null);該reverse方法將毫無問題地終止。有人能解釋一下這是怎么回事嗎?編輯:我剛剛意識到 3 個或更多的不同行為size只是遞歸的產物。真正的問題在于當size等于 2 時該方法莫名其妙地終止于該行this.tail = n;
查看完整描述

1 回答

?
Helenr

TA貢獻1780條經驗 獲得超4個贊

的實現removeFirstNode()不會取消節點的下一個指針的鏈接。


原始鏈表中,第一個節點的next指針指向第二個節點,第二個節點的next指針為空。


在新鏈表中,第一個節點的 next 指針將指向第二個節點,但第二個節點的 next 指針將指向第一個節點(以前是第二個節點)。


像這樣的東西(原始列表):


+---+    +---+

| A |--->| B |--->null

+---+    +---+

當重新排序時變成這樣,因為 A 的下一個指針仍然指向 B:


+---+    +---+

| B |--->| A |---+

+---+    +---+   |

  ^              |

  |              |

  +--------------+

您可以將您的removeFirstNode()實現更改為如下所示:


    private Node<E> removeFirstNode() {

        if (isEmpty()) return null;

        Node<E> answer = this.head;

        this.head = this.head.getNext();

        answer.next = null; // Set next ptr to null

        this.size--;

        if (this.size == 0) {

            this.tail = null;

        }

        return answer;

    }

該代碼可能看起來像“停止”,因為調試器嘗試使用 打印出列表toString(),我想它會遍歷列表并且由于循環而永遠不會完成。


查看完整回答
反對 回復 2023-06-21
  • 1 回答
  • 0 關注
  • 159 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號