Algorithm 给定一个树结构,如何使用递归使其成为一个简单的链表?
给定一个二叉树(只有左、右两个子树),如何编写递归函数使其成为一个简单的链表?(不应创建新的数据结构。伪代码可以)。假设每个节点都有一个整数值,如123、2或3。最终链接列表应该包含树中的所有节点。顺序并不重要Algorithm 给定一个树结构,如何使用递归使其成为一个简单的链表?,algorithm,recursion,Algorithm,Recursion,给定一个二叉树(只有左、右两个子树),如何编写递归函数使其成为一个简单的链表?(不应创建新的数据结构。伪代码可以)。假设每个节点都有一个整数值,如123、2或3。最终链接列表应该包含树中的所有节点。顺序并不重要 更新:需要到位。不应创建新的数据结构。您真的在问我如何遍历二叉树。答案可以在任何一本关于算法和数据结构的书中找到。你真的在问我如何走二叉树。答案可以在任何一本关于算法和数据结构的书中找到。在树上迭代总是有不同的方法,如下所示: 有序 预购 邮购 您可以选择其中任何一个来形成您的列表
更新:需要到位。不应创建新的数据结构。您真的在问我如何遍历二叉树。答案可以在任何一本关于算法和数据结构的书中找到。你真的在问我如何走二叉树。答案可以在任何一本关于算法和数据结构的书中找到。在树上迭代总是有不同的方法,如下所示:
- 有序
- 预购
- 邮购
请记住:如果您在二叉搜索树上执行索引,您将按排序顺序获取元素。在树上迭代总是有不同的方法,如下所示:
- 有序
- 预购
- 邮购
记住:如果你在二叉搜索树上执行了一个顺序,你会得到按顺序排列的元素。不必粗鲁,但这听起来有点像家庭作业。让我描述一下,作为回答:
- 为结果创建一个空的链接列表
- 制作一个帮助函数,它包含一个链表和一个节点
- helper函数应该将子节点(如果有)添加到列表中,并在子节点(如果有)上递归调用自己
- 将根节点添加到结果列表中
- 在根节点和结果列表上调用helper函数
- 将结果列表返回给调用者
编辑:或查看凯文发布的伪代码:-)不要粗鲁,但这听起来有点像家庭作业。让我描述一下,作为回答:
- 为结果创建一个空的链接列表
- 制作一个帮助函数,它包含一个链表和一个节点
- helper函数应该将子节点(如果有)添加到列表中,并在子节点(如果有)上递归调用自己
- 将根节点添加到结果列表中
- 在根节点和结果列表上调用helper函数
- 将结果列表返回给调用者
def in_walk(tree, doit):
if tree is null: return
in_walk(tree.left, doit)
doit(tree.root)
in_walk(tree.right, doit)
我希望这个伪代码中的假设是显而易见的:一棵树有左链接和右链接,可以是空的,意思是“这里没有什么可走的”,还有一个根节点;对于给定的节点参数,您可以传递正确思考的函数或闭包(附加到链表或其他任何内容)。您可以按许多顺序“遍历树”,主要顺序为前、后和顺序。以下是顺序的一些伪代码,例如:
def in_walk(tree, doit):
if tree is null: return
in_walk(tree.left, doit)
doit(tree.root)
in_walk(tree.right, doit)
/* bst.c: sort the input numbers and print them forward and backward with no duplicates */
#include <stdio.h>
#include <stdlib.h>
struct node {
int key;
struct node *left;
struct node *right;
};
static struct node **bst_find(struct node **root, int key) {
struct node **n;
n = root;
while (*n != NULL && (*n)->key != key) {
if (key < (*n)->key) {
n = &(*n)->left;
} else {
n = &(*n)->right;
}
}
return n;
}
static void bst_insert(struct node **root, int key) {
struct node **n;
n = bst_find(root, key);
if (*n == NULL) {
*n = malloc(sizeof (**n));
(*n)->key = key;
(*n)->left = NULL;
(*n)->right = NULL;
}
}
/* massage the tree rooted at "root" to be a doubly-linked list
* return the leftmost and rightmost nodes via the parameters "leftend" and "rightend"
* bst_flatten() is invoked 2N+1 times, where N is the number of tree elements
*/
static long Flatten_count = 0;
static void bst_flatten(struct node **leftend, struct node **rightend, struct node *root) {
Flatten_count++;
if (root != NULL) {
/* flatten the left side of the tree */
*leftend = root;
bst_flatten(leftend, &root->left, root->left);
/* if necessary, splice "root" onto the right end */
if (root->left != NULL) {
root->left->right = root;
}
/* flatten the right side of the tree */
*rightend = root;
bst_flatten(&root->right, rightend, root->right);
/* if necessary, splice "root" onto the left end */
if (root->right != NULL) {
root->right->left = root;
}
}
}
int main(void) {
int key;
long N = 0;
struct node *root = NULL;
struct node *leftend = NULL;
struct node *rightend = NULL;
struct node *n;
/* read the input into a bst */
while (scanf("%d", &key) == 1) {
N++;
bst_insert(&root, key);
}
/* make a list */
bst_flatten(&leftend, &rightend, root);
/* traverse the list forward */
for (n = leftend; n != NULL; n = n->right) {
printf("%d\n", n->key);
}
/* traverse the list backward */
for (n = rightend; n != NULL; n = n->left) {
printf("%d\n", n->key);
}
fprintf(stderr, "%ld items input, %ld invocations of bst_flatten()\n", N, Flatten_count);
return 0;
}
我希望这个伪代码中的假设是显而易见的:一棵树有左链接和右链接,可以是空的,意思是“这里没有什么可走的”,还有一个根节点;您可以传递一个函数或闭包,该函数或闭包在给定节点参数的情况下进行正确思考(附加到链表或其他任何内容)。/*bst.c:对输入的数字进行排序,并向前和向后打印,不重复*/
/* bst.c: sort the input numbers and print them forward and backward with no duplicates */
#include <stdio.h>
#include <stdlib.h>
struct node {
int key;
struct node *left;
struct node *right;
};
static struct node **bst_find(struct node **root, int key) {
struct node **n;
n = root;
while (*n != NULL && (*n)->key != key) {
if (key < (*n)->key) {
n = &(*n)->left;
} else {
n = &(*n)->right;
}
}
return n;
}
static void bst_insert(struct node **root, int key) {
struct node **n;
n = bst_find(root, key);
if (*n == NULL) {
*n = malloc(sizeof (**n));
(*n)->key = key;
(*n)->left = NULL;
(*n)->right = NULL;
}
}
/* massage the tree rooted at "root" to be a doubly-linked list
* return the leftmost and rightmost nodes via the parameters "leftend" and "rightend"
* bst_flatten() is invoked 2N+1 times, where N is the number of tree elements
*/
static long Flatten_count = 0;
static void bst_flatten(struct node **leftend, struct node **rightend, struct node *root) {
Flatten_count++;
if (root != NULL) {
/* flatten the left side of the tree */
*leftend = root;
bst_flatten(leftend, &root->left, root->left);
/* if necessary, splice "root" onto the right end */
if (root->left != NULL) {
root->left->right = root;
}
/* flatten the right side of the tree */
*rightend = root;
bst_flatten(&root->right, rightend, root->right);
/* if necessary, splice "root" onto the left end */
if (root->right != NULL) {
root->right->left = root;
}
}
}
int main(void) {
int key;
long N = 0;
struct node *root = NULL;
struct node *leftend = NULL;
struct node *rightend = NULL;
struct node *n;
/* read the input into a bst */
while (scanf("%d", &key) == 1) {
N++;
bst_insert(&root, key);
}
/* make a list */
bst_flatten(&leftend, &rightend, root);
/* traverse the list forward */
for (n = leftend; n != NULL; n = n->right) {
printf("%d\n", n->key);
}
/* traverse the list backward */
for (n = rightend; n != NULL; n = n->left) {
printf("%d\n", n->key);
}
fprintf(stderr, "%ld items input, %ld invocations of bst_flatten()\n", N, Flatten_count);
return 0;
}
#包括
#包括
结构节点{
int键;
结构节点*左;
结构节点*右;
};
静态结构节点**bst\U查找(结构节点**根,int键){
结构节点**n;
n=根;
while(*n!=NULL&&(*n)->key!=key){
如果(键<(*n)->键){
n=&(*n)->左;
}否则{
n=&(*n)->右;
}
}
返回n;
}
静态无效bst_插入(结构节点**根,int键){
结构节点**n;
n=bst_查找(根,键);
如果(*n==NULL){
*n=malloc(sizeof(**n));
(*n)->key=key;
(*n)->left=NULL;
(*n)->right=NULL;
}
}
/*将根在“根”的树按摩为双链接列表
*通过参数“leftend”和“rightend”返回最左边和最右边的节点
*bst_flatte()被调用2N+1次,其中N是树元素的数量
*/
静态长展平计数=0;
静态无效bst_展平(结构节点**左端,结构节点**右端,结构节点*根){
展平计数++;
if(root!=NULL){
/*把树的左边压平*/
*左端=根;
bst_展平(左端,&根->左,根->左);
/*如有必要,将“根部”拼接到右端*/
如果(根->左!=NULL){
根->左->右=根;
}
/*把树的右边压平*/
*右端=根;
bst_展平(&root->right,rightend,root->right);
/*如有必要,将“根部”拼接到左端*/
如果(根->右!=NULL){
根->右->左=根;
}
}
}
内部主(空){
int键;
长N=0;
结构节点*root=NULL;
结构节点*leftend=NULL;
结构节点*rightend=NULL;
结构节点*n;
/*将输入读入bst*/
while(scanf(“%d”,&key)==1){
N++;
bst_插入(&根,键);
}
/*列一张清单*/
bst_展平(左端和右端,根);
/*向前遍历列表*/
对于(n=leftend;n!=NULL;n=n->right){
printf(“%d\n”,n->key);
}
/*向后遍历列表
public void AppendTreeToLinkedList<T>(Node<T> node, LinkedList<T> list)
{
if (node.LeftChild != null)
AppendTreeToLinkedList(node.LeftChild, list);
list.Append(node.Value);
if (node.RightChild != null)
AppendTreeToLinkedList(node.RightChild, list);
}
listify( node )
if node has no children
return
else if node.left == null
listify(node.right)
else if node.right == null
listify(node.left)
mode.right = node.left
else
listify(node.left)
listify(node.right)
temp = node.left
while temp.right != null
temp = temp.right
temp.right = node.right
node.right = node.left
function Listify(Node n, out Node First, out Node Last)
{
if ( Node.Left != null )
{
Node Tmp;
Listify(Node.Left, out First, out Tmp);
Node.Left = Tmp;
}
else
{
First = Node;
}
if ( Node.Right != null )
{
Node Tmp;
Listify(Node.Right, out Tmp, out Last);
Node.Right = Tmp;
}
else
{
Last = Node;
}
}
(define (tree->list tree)
(define empty-set (list))
(define (copy-to-list tree result-list)
(if (null? tree)
result-list
(copy-to-list (left-branch tree)
(cons (entry tree)
(copy-to-list (right-branch tree)
result-list)))))
(copy-to-list tree empty-set))
(define (entry tree) (car tree))
(define (left-branch tree) (cadr tree))
(define (right-branch tree) (caddr tree))
(define (make-tree entry left right)
(list entry left right))