Algorithm 给定一个树结构,如何使用递归使其成为一个简单的链表?

Algorithm 给定一个树结构,如何使用递归使其成为一个简单的链表?,algorithm,recursion,Algorithm,Recursion,给定一个二叉树(只有左、右两个子树),如何编写递归函数使其成为一个简单的链表?(不应创建新的数据结构。伪代码可以)。假设每个节点都有一个整数值,如123、2或3。最终链接列表应该包含树中的所有节点。顺序并不重要 更新:需要到位。不应创建新的数据结构。您真的在问我如何遍历二叉树。答案可以在任何一本关于算法和数据结构的书中找到。你真的在问我如何走二叉树。答案可以在任何一本关于算法和数据结构的书中找到。在树上迭代总是有不同的方法,如下所示: 有序 预购 邮购 您可以选择其中任何一个来形成您的列表

给定一个二叉树(只有左、右两个子树),如何编写递归函数使其成为一个简单的链表?(不应创建新的数据结构。伪代码可以)。假设每个节点都有一个整数值,如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))