生成二叉树

1.Construct Binary Tree from Inorder and Postorder Traversal

  1. 问题描述
    由中序遍历和后续遍历生成二叉树
  2. 解题思路
    方法一:时间O(n2) ,空间 O(1)
public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(inorder == null || postorder == null)
            return null;
        int iLength = inorder.length;
        int pLength = postorder.length;
        if(iLength == 0 || pLength == 0)
            return null;
        return buildNode(inorder,0,iLength-1,postorder,0,pLength-1);
    }

    public TreeNode buildNode(int[] inorder, int iB, int iE, int[] postorder, int pB, int pE) {
        if(iB == iE){
            TreeNode node = new TreeNode(inorder[iB]);
            return node;
        }else if(iB > iE)
            return null;
        TreeNode root = new TreeNode(postorder[pE]);
        int index = findIndex(inorder,iB,iE,postorder[pE]);
        int llength = index - iB;
        int leftBeginIn = iB;
        int leftEndIn = index - 1;
        int leftBeginPost = pB;
        int leftEndPost = pB +  llength - 1;
        root.left = buildNode(inorder,leftBeginIn,leftEndIn,postorder,leftBeginPost,leftEndPost);
        int rightBeginIn = index + 1;
        int rightEndIn = iE;
        int rightBeginPost = pB +  llength;
        int rightEndPost = pE - 1;
        root.right = buildNode(inorder,rightBeginIn,rightEndIn,postorder,rightBeginPost,rightEndPost);
        return root;

    }

    public int findIndex(int[] Nums,int iB,int iE,int target){
        for(int i = iB; i <= iE; i++){
            if(Nums[i] == target)
                return i;
        }
        return -1;
    }

方法二:使用哈希表。时间复杂度O(n),空间O(n)

public TreeNode buildTreePostIn(int[] inorder, int[] postorder) {
    if (inorder == null || postorder == null || inorder.length != postorder.length)
        return null;
    HashMap<Integer, Integer> hm = new HashMap<Integer,Integer>();
    for (int i=0;i<inorder.length;++i)
        hm.put(inorder[i], i);
    return buildTreePostIn(inorder, 0, inorder.length-1, postorder, 0, 
                          postorder.length-1,hm);
}

private TreeNode buildTreePostIn(int[] inorder, int is, int ie, int[] postorder, int ps, int pe, 
                                 HashMap<Integer,Integer> hm){
    if (ps>pe || is>ie) return null;
    TreeNode root = new TreeNode(postorder[pe]);
    int ri = hm.get(postorder[pe]);
    TreeNode leftchild = buildTreePostIn(inorder, is, ri-1, postorder, ps, ps+ri-is-1, hm);
    TreeNode rightchild = buildTreePostIn(inorder,ri+1, ie, postorder, ps+ri-is, pe-1, hm);
    root.left = leftchild;
    root.right = rightchild;
    return root;
}

2.Construct Binary Tree from Preorder and Inorder Traversal

  1. 问题描述
    由先序遍历和中续遍历生成二叉树
  2. 解题思路
    方法一:时间O(n) ,空间 O(n)
public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder == null || inorder == null)
            return null;
        int preLength = preorder.length;
        int inLength = inorder.length;
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i = 0; i < inLength; i++){
            map.put(inorder[i], i);
        }
        return buildNode(preorder,0,preLength-1,inorder,0,inLength-1,map);
    }

public TreeNode buildNode(int[] preorder, int pB, int pE, int[] inorder, int iB, int iE,HashMap<Integer,Integer> map){
        if(iB > iE)
            return null;
        if(iB == iE){
            TreeNode root = new TreeNode(inorder[iB]);
            return root;
        }
        TreeNode root = new TreeNode(preorder[pB]);
        int index = map.get(preorder[pB]);
        int length = index - iB;
        root.left = buildNode(preorder, pB+1, pB+length, inorder, iB, index-1,map);
        root.right = buildNode(preorder, pB+length+1, pE, inorder, index+1, iE,map);
        return root;
    }
<think>嗯,用户想用C语言实现随机生成二叉树的功能。首先,我需要回忆一下二叉树的结构。二叉树每个节点通常包含数据、左子树和右子树指针。那用户给的示例代码是用前序遍历手动输入的,但现在需要改成随机生成。 那随机生成的话,应该考虑如何随机决定节点的存在与否,以及节点的数据内容。可能需要设置一个随机生成的概率,比如每个节点有50%的概率生成左子节点和右子节点。同时,数据部分可以用随机字符或者数字填充。 首先,我需要用C语言的rand()函数来生成随机数。记得要设置种子,通常用srand(time(NULL))来初始化。然后,在创建节点时,随机决定是否继续生成左右子树。例如,当递归创建左子树时,生成一个随机数,如果小于某个阈值(比如RAND_MAX/2),则继续生成,否则停止,左子树为NULL。 接下来,数据部分可以随机选择字符,比如从'A'到'Z'之间随机选一个。可以用rand() % 26 + 'A'来实现。这样每个节点的数据都是随机大写字母。 另外,原来的代码是用户输入生成,现在要改成自动生成,所以需要修改CrtBit函数,去掉scanf的部分,换成随机生成逻辑。可能还需要调整函数参数,比如添加一个层数参数,控制树的深度,防止无限递归或者栈溢出。例如,当层数超过一定值时,停止生成子节点。 测试的时候,主函数里调用生成函数后,用遍历函数打印节点,确保生成的树结构正确。同时要注意内存管理,不过示例代码中没有释放内存,可能需要提醒用户添加free函数,避免内存泄漏。 可能的问题点:随机生成的树可能不平衡,或者深度过大导致栈溢出。所以需要设置最大层数限制,比如在递归时传入当前层数,当达到最大值时不再生成子节点。例如,设置MAX_DEPTH为5,层数超过5则返回NULL。 然后,根据这些思路,编写代码。先定义节点结构体,然后写生成函数,在生成函数中使用随机数决定是否创建左右子节点,数据随机生成。同时,遍历函数可以用前序遍历来验证结果。 最后,测试代码,确保没有编译错误,运行后能生成随机二叉树并正确打印节点信息。可能还需要处理一些细节,比如在生成随机数时避免重复相同的种子,或者调整生成概率来控制树的形状。</think>以下是用C语言实现随机生成二叉树的代码示例,包含自动生成节点和随机数据功能: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX_DEPTH 5 // 最大生成深度 #define TITLE "----------自动生成二叉树演示程序----------" typedef struct BitNode { char data; struct BitNode* lt; struct Bit Node* rt; } BitNode, *BitPtr; /* 随机生成二叉树(带深度控制)*/ void RandomCreateTree(BitPtr* root, int level) { if (level > MAX_DEPTH || rand() % 2 == 0) { // 随机终止条件[^1] *root = NULL; return; } *root = (BitPtr)malloc(sizeof(BitNode)); (*root)->data = 'A' + rand() % 26; // 随机生成大写字母 RandomCreateTree(&(*root)->lt, level + 1); RandomCreateTree(&(*root)->rt, level + 1); } /* 前序遍历打印树结构*/ void PrintTree(BitPtr root, int level) { if (!root) return; printf("层级 %d: %c\n", level, root->data); PrintTree(root->lt, level + 1); PrintTree(root->rt, level + 1); } /* 释放内存*/ void FreeTree(BitPtr root) { if (root) { FreeTree(root->lt); FreeTree(root->rt); free(root); } } int main() { srand(time(NULL)); // 初始化随机种子 BitPtr root = NULL; printf("%s\n", TITLE); RandomCreateTree(&root, 1); PrintTree(root, 1); FreeTree(root); return 0; } ``` 代码说明: 1. 使用$rand()$函数控制节点生成概率,每个节点有50%概率继续生成子树[^1] 2. 节点数据随机生成大写字母(范围$'A'$到$'Z'$) 3. 设置$MAX_DEPTH$防止生成过深树结构 4. 包含内存释放函数避免内存泄漏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值