将节点插入链表的末尾
对于这些问题有一个简单的迭代解决方案。
Node Insert(Node head,int data) {
Node newNode = new Node();
newNode.data = data;
if (head == null) {
return newNode;
}
Node current = head;
while (current.next != null) {
current = current.next;
}
current.next = newNode;
return head;
}
它工作得很好。 但我想学习递归并从这个角度看待事物。 因此,我提出了下面的解决方案,它看起来很优雅,但我不得不承认,这只是直觉 ,而且给定的代码起作用。 我想开发一个用递归工作的心智模型,或者至少有一些方法来验证我的代码能够正常工作。 如何从理论上验证下面的解决方案应该起作用。
递归版本
Node Insert(Node head,int data) {
// Base case.
if (head == null) {
Node newNode = new Node();
newNode.data = data;
return newNode;
}
// Smaller problem instance.
head.next = Insert(head.next, data);
return head;
}
递归解决方案通常必须遵守这些规则:
if
)到两个代码块:基本块和通用块。 在corse中,这是一个简单的递归模型,实际上它可能更复杂(不止一个基本情况,两个函数之间的递归等)。
如果我们根据这些规则在理论上分析您的建议,我们可以看到它满足所有这些规则。
我会稍微深入一些,并删除多个退出点。 这使您可以推理列表中的效果以及返回哪个节点mut。
Node appendRecursive(Node head, int data) {
// By default return the same list we were given.
Node list = head;
if (list == null) {
// At end of list or list is empty.
list = new Node();
list.data = data;
} else {
// Recurse.
head.next = appendRecursive(head.next, data);
}
return list;
}
就推理而言,你通常需要使用归纳。
list == null
),则创建一个新节点并成为您的列表。 鉴于上述情况,可以推断在所有情况下,这将正确运行,因为列表为空或不是。
使用列表上的递归通常被认为是低效和笨重的,因为迭代算法更适合线性结构。 更好的练习是编写自己的Tree
结构,因为树可以很好地适应递归算法。 你会发现在树上递归地执行所需的函数通常要容易得多,也更加优雅。
static class Tree {
Node head = null;
class Node {
Node left;
Node right;
int data;
private Node(int data) {
this.data = data;
}
}
void insert(int data) {
head = insert(head, data);
}
private Node insert(Node node, int data) {
if (node == null) {
// Empty tree becomes just the node.
return new Node(data);
} else {
// Pick the correct branch to add this data to.
if (data < node.data) {
node.left = insert(node.left, data);
} else {
node.right = insert(node.right, data);
}
}
return node;
}
private CharSequence toString(Node n) {
StringBuilder s = new StringBuilder();
if (n != null) {
// First print the tree on the left.
if (n.left != null) {
s.append(toString(n.left)).append(",");
}
// Then the data in this node.
s.append(n.data);
// Then the tree on the right.
if (n.right != null) {
s.append(",").append(toString(n.right));
}
}
return s;
}
@Override
public String toString() {
// Even toString is recursive.
StringBuilder s = new StringBuilder("{");
s.append(toString(head));
return s.append("}").toString();
}
}
public void test() {
Tree tree = new Tree();
for (int i : new int[]{6, 5, 4, 3, 2, 1}) {
tree.insert(i);
}
System.out.println(tree);
}
请注意,判断在toString
方法中添加“,”的方式非常简单 - 打印列表时出现一个臭名昭着的严重问题。
Node Insert(Node head,int data) {
if (head == null) {
head = new Node();
head.data = data;
}
else{
head.next = Insert(head.next, data);
}
return head;
}
假设你有5,3,2,1,并且你想添加4然后: - insert(node(5),int 4)
if( node(5) == null )
no then head.next = node(5).next
是node(3)
并调用Insert(node(3),4)
if( node(3) == null )
no then head.next = node(3).next
是node(2)
并调用Insert(node(2),4)
if( node(2) == null )
no then head.next = node(2).next
,它是node(1)
并调用Insert(node(1),4)
if( node(1) == null )
没有那么head.next = node(1).next
是null
“ 因为有后没有元素 node(1)
和呼叫Insert(node(1).next,4)
(node(1).next) == null
yes then set head = new node ();
并设置数据head = new node ();
在最后回头
上一篇: Insert node at the end of linked list
下一篇: Mixed mode assembly is built against version ‘v2.0.50727′ of the runtime