这更多是因为我缺乏理解SortedList类的能力。我理解的ListNode:它是一个由2个东西组成的节点:一个可比对象和一个ListNode对象,它本身有两个相同的东西。
我不明白插入和删除方法如何在下面的SortedList类中工作。 理解起来非常复杂。在SortedList类中,如果头为null,则指向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));
}
}
答案 0 :(得分:2)
curr
时,{p> null
为insert
。所以while
暂时被忽略了。
但是当prev == null
求值为true时,如果块被执行,基本上执行这一行:
head = new ListNode(x, curr);
有了这个,head
不再有null
,而对insert
的任何进一步调用都可能导致while
循环被执行。是否将执行while
循环取决于以下表达式:
x.compareTo(curr.getData()) > 0
如果true
,while
被执行,则不会。
答案 1 :(得分:1)
在第一个声明中,你的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不为null,让它进入循环
答案 2 :(得分:1)
您需要分解(比方说)insert
方法的功能。
新节点(通常)将插入两个节点之间......除非您最终插入列表的开头和结尾。
局部变量初始化设置了一些内容,以便我们开始查看循环的开头。 <{1}}变量将指向插入点之前的节点。 <{1}}变量将指向插入点后的节点。
prev
循环找到插入点。它遍历列表节点,直到找到大于或等于curr
的节点。插入点是之前的节点。如果列表为空(即while
为x
),则插入点是列表的开头。完成后(包括永不运行的情况),head
和null
将具有最终部分所需的值...
while循环后的代码执行插入,在prev
节点和curr
节点之间插入新节点。如果prev
为curr
,则必须以不同方式处理。
所以回答你的问题:
但是哪个代码使curr不为null呢?
没有代码那样做。它不需要不为null。
在您正在进行插入时,prev
是插入点之后的节点。如果要插入列表末尾(或插入空列表),插入点后面没有节点,null
将(应该)curr
。
插入单个链接列表有点棘手,但要记住的关键是任何算法都需要在要插入的位置之前找到并更新节点新节点。删除也是如此。