【问题标题】:How does insert and delete method of SortedList in Java workJava中SortedList的插入和删除方法是如何工作的
【发布时间】:2013-03-16 23:59:55
【问题描述】:

这更多是因为我缺乏理解 SortedList 类的能力。我理解的 ListNode:它是一个由 2 个东西组成的节点:一个可比较的对象和一个 ListNode 对象,它本身具有相同的 2 个东西。

我不明白下面的 SortedList 类中的插入和删除方法是如何工作的。 理解起来非常复杂。在 SortedList 类中,如果 head 为 null,则指向 curr。 curr 不应该为空吗?那么while循环不应该执行,但实际上当我使用println测试执行时它确实执行了。

ListNode 类的代码:

public class ListNode {

    private Comparable data;
    private ListNode next;

    public ListNode() {
        data = null;
        next = null;
    }

    public ListNode(Comparable x) {
        data = x;
        next = null;
    }

    public ListNode(Comparable x, ListNode nextListNode) {
        data = x;
        next = nextListNode;
    }

    public Comparable getData() {
        return data;
    }

    public ListNode getNext() {
        return next;
    }

    public void setData(Comparable x) {
        data = x;
    }

    public void setNext(ListNode nextListNode) {
        next = nextListNode;
    }

}

SortedList 的代码:

public class SortedList {

    private ListNode head;

    public SortedList() {
        head = null;
    }

    public void insert(Comparable x) {
        ListNode curr = head, prev = null;
        while (curr != null && x.compareTo(curr.getData()) > 0) {
            prev = curr;
            curr = curr.getNext();
        }
        if (prev == null) {
            head = new ListNode(x, curr);
        } else {
            prev.setNext(new ListNode(x, curr));
        }
    }

    public boolean delete(Comparable x) {
        if (head == null) {
            return false;
        }
        ListNode curr = head, prev = null;
        while (curr != null && x.compareTo(curr.getData()) > 0) {
            prev = curr;
            curr = curr.getNext();
        }
        if (curr == null || x.compareTo(curr.getData()) != 0) {
            return false;
        }
        if (prev == null) {
            head = curr.getNext();
        } else {
            prev.setNext(curr.getNext());
        }
        return true;
    }

    public void output() {
        for (ListNode curr = head; curr != null; curr = curr.getNext()) {
            System.out.println(curr.getData());
        }
    }

}

TestSortedList 的代码:

public class TestSortedList {

    public static void main(String[] args) {
        SortedList list = new SortedList();
        list.insert(5);
        list.insert(1);
        list.insert(10);
        list.insert(3);
        list.insert(7);
        list.output();
        System.out.println(list.delete(5));
        System.out.println(list.delete(5));
        System.out.println(list.delete(1));
        System.out.println(list.delete(10));
        System.out.println(list.delete(11));
    }

}

【问题讨论】:

  • 对于第一个insert循环while没有执行,你认为为什么会执行?
  • @michal.szpruta 它第一次没有执行 while 循环。但我无法弄清楚为什么循环在这之后执行,这意味着 curr 在第一次插入后不为空。

标签: java sortedlist


【解决方案1】:

当第一次调用insert 时,currnull。所以while 这次被忽略了。

但是当prev == null 的计算结果为真时,如果块被执行,本质上就是执行这一行:

head = new ListNode(x, curr);

这样,head 将不再存在 null,并且对 insert 的任何进一步调用都可能导致 while 循环被执行。 while 循环是否会被执行取决于这个表达式:

x.compareTo(curr.getData()) > 0

如果truewhile 被执行,否则不执行。

【讨论】:

  • 我现在明白了!你的解释太棒了!绿色检查!
【解决方案2】:

您需要分解(比如说)insert 方法的功能。

  • 新节点(通常)将插入两个节点之间...除非您最终插入到列表的开头和结尾。

  • 局部变量初始化设置,以便我们开始查看循环的开头。 prev 变量将指向插入点 before 的节点。 curr 变量将指向插入点之后的节点。

  • while 循环找到插入点。它遍历列表节点,直到找到大于或等于x 的节点。插入点在该节点之前。如果列表为空(即headnull),则插入点是列表的开头。当它完成时(包括它从不运行的情况),prevcurr 将具有最终部分所需的值...

  • while 循环之后的代码进行插入,在prev 节点和curr 节点之间插入新节点。如果prevnull,它必须以不同的方式处理事情。


所以回答你的问题:

但是哪段代码让 curr 不为空呢?

没有代码可以做到这一点。它不需要不为空。

在您实际进行插入时,curr 是插入点之后的节点。如果您在列表末尾插入(或插入空列表),则插入点之后没有节点,curr 将(并且应该)为null


插入单链表有点棘手,但要记住的关键是任何算法都需要在您要插入的位置之前找到并更新节点新节点。删除也是如此。

【讨论】:

  • 是的,我很难理解它。我会记住你的关键:在插入新节点之前更新。
【解决方案3】:

在第一条语句中,你的 while 循环有:

while(curr != null && x.compareTo(curr.getData()) >0 )

当您调用 x.compareTo(curr.getData()) 时,您将 5 与 null 进行比较,它返回 1。大于 0,所以一半的要求是正确的,但它仍然跳过 while 循环并继续到

 if (prev == null) {
        head = new ListNode(x, curr);

这个动作给 head 一个值,它不再是 null。所以当你第二次插入时,你会这样做

ListNode curr = head;

这一次,curr 不为空,让它进入循环

【讨论】:

  • 但是 curr 首先被评估并且它是空的。为什么 curr 不会变为空? while 循环是短路评估的。
  • 当第一次调用 insert 时,currnull。所以while 这次被忽略了。
  • @NishantShreshth 正确。但是哪个代码使 curr 不为空呢?
  • @BrettD 你的解释太棒了+1!
猜你喜欢
  • 1970-01-01
  • 2012-09-19
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
  • 2011-02-11
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多