我有以下代码来反转链接列表:
public class ProgrammingInterviews {
public static void main(String[] args) {
List list = new List();
list.add(new Node(1));
list.add(new Node(2));
list.add(new Node(3));
list.add(new Node(4));
list.reverse();
System.out.println(list);
}
}
class List {
Node head;
public List() {
head = new Node(0);
}
public void add(Node node) {
if (head.next == null) {
head.next = node;
} else {
Node temp = head.next;
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
}
}
public void reverse() {
this.head = reverse(this.head);
}
private Node reverse(Node n) {
if (n == null || n.next == null) {
return n;
}
Node remaining = reverse(n.next);
n.next.next = n;
n.next = null;
return remaining;
}
public String toString() {
Node temp = head;
String result = "HEAD";
while (temp.next != null) {
result = result + "->" + temp.next.data;
temp = temp.next;
}
return result;
}
}
class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
}
}
我试图让它打印HEAD->4->3->2->1
但没有用。但是,它正在打印HEAD->3->2->1
。我有什么遗失的。
另外,如果您有如何解决这些类型问题的提示,那将对我有所帮助。我已经做了一段时间的编程了。它非常适合解决问题。我很容易想出天真的解决方案。但是,在数据结构和算法的领域,我们通过不同的想法/方式思考提出解决方案,我总是觉得很短。
例如,在这个问题中,我从未想过使用递归有一个解决方案。我正在使用其他地方查找的解决方案。如果我得到一些技巧可以帮助我解决这些类型的问题,那将会非常有用。
答案 0 :(得分:0)
问题在于如何概念化链表的头部。构建列表时,请指定:
public List() {
head = new Node(0);
}
该列表理论上是空的,但我们已经有了一个元素!您的数据结构并不能准确地表示数据,但在大多数情况下,您可以通过查看head.next来忽略它。例如:
public String toString() {
Node temp = head;
String result = "HEAD";
while (temp.next != null) {
result = result + "->" + temp.next.data;
temp = temp.next;
}
return result;
}
你正在通过查看temp.next来查看列表。由于我们从头开始,我们从不看它的值,我们打印的第一个值是head.next(如果它不是null)。
现在,看一下反向方法:
public void reverse() {
this.head = reverse(this.head);
}
听起来有点奇怪吗?我们有假的价值,我们故意忽略它,但现在我们已经覆盖了它。我们用它覆盖了什么?
好吧,如果reverse()
正常工作,新头将是旧的最后一个元素。在你的情况下,那将是...... 4元素!但是我们忽略了toString()
中的头部,所以4将永远不会被打印出来。
我运行你提供的代码,它实际上打印HEAD->3->2->1->0
,这不应该是一个惊喜,因为列表被反转,而ghost 0元素现在已被推到最后。
我的建议是尝试保持结构简单:当列表为空时,头部应该为空。而不是while(temp.next != null)
,也许你可以做while(temp != null)
,因为我们不再有一个基节点(如果头为空,head.next是非法的),最后temp.next
element的next应始终为null(这不适用于add()
,因为我们需要对最后一个元素的引用)。