西工大数据结构NOJ18--建立二叉树的二叉链表

 

 

写完NOJ后看了一眼csdn,发现并没有人把算法的分析过程发出来。我使用的算法参考的是书上的第179页给出的算法流程,发出来供大家交流讨论。
首先题目给出我们一个前序序列和一个中序序列,要求输出后序序列。第一想法便是通过前序序列和中序序列建立一个二叉树,再通过后序遍历输出。那么,我们如何通过前序和中序确定一个二叉树呢?我们先明确前序和中序的特点。前序的访问顺序是根-左结点-右结点,中序则是左结点-根-右结点。我们可以发现前序中第一个结点一定是根结点。
OK,算法的设计思路来了,用一下分治的思想,我们可以找到前序的第一个结点,然后以此将中序序列分成左右子树,将左右子树的序列分别传给我们的创建二叉树的函数,反复如此(相信经过前三题的历练,大伙对递归已经有了一定的理解,这里递归部分直接贴代码),注意,前序序列只需要用同一个就行,你需要做的就是在当前中序的序列中,找到其中出现的第一个对应的前序序列中的结点,即可。是不是已经有思路了?可以尝试自己动手实践了!
老规矩,结尾贴上AC的源码并附上NOJ的测试样例,方便大伙调试。祝诸君学业有成,希望大伙可以点赞支持,抱拳。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* NOJ_18.c,建立二叉树的二叉链表
 * 由一个二叉树的前序序列和中序序列,输出后序序列
 * 编译:gcc NOJ_18.c -o NOJ_18.exe
 * 运行:./NOJ_18.exe
 * 输入:分两行分别输入一颗二叉树的前序和中序序列
 * 输出:输出该二叉树的后序序列
 *
 * author:Aimer
 * date: 2023-05-11
 */
//定义数据域类型
typedef char ElemType;
//定义二叉树节点
typedef struct BinTreeNode
{
    ElemType data;              //数据域
    struct BinTreeNode * left;  //左节点
    struct BinTreeNode * right; //右节点
}BinTreeNode,*PBinTreeNode;
//函数声明
void createBinTree(PBinTreeNode,char*,char*);//创捷二叉树
void postOrderOutput(PBinTreeNode);          //后序输出
//程序入口
int main(int argc,char* argv[])
{
    char str_pre[1000] = {0};
    char str_in[1000] = {0};
    scanf("%s",str_pre);
    scanf("%s",str_in);
    PBinTreeNode root = (PBinTreeNode)malloc(sizeof(BinTreeNode));
    createBinTree(root,str_pre,str_in);
    
    postOrderOutput(root);
    free(root);
    return 0;
}
/* 创建二叉树
 * node,一个二叉树节点指针,str_pre该树的前序序列,str_in中序
 * 通过前序确定节点,再中序中分割
 * 通过递归方式创建
*/
void createBinTree(PBinTreeNode node,char* str_pre,char* str_in)
{
    int i = 0,j=0,len = strlen(str_in);
    while(str_pre[j] != str_in[i])
    {
        if(i == strlen(str_in))
        {
            j++,i=0;
            continue;
        }
           i++;
    }
    node->data = str_pre[j];
    if(i==0)//如果没有左节点
        node->left = NULL;
    if(i==strlen(str_in)-1)
        node->right = NULL;
    if(i>0)
    {
        node->left = (PBinTreeNode)malloc(sizeof(BinTreeNode));
        char* str_left = (char*)malloc(sizeof(char)*(i+1));//多开一个空间用于填放'\0'
        for(int k=0;k<i;k++)
        {
            str_left[k] = str_in[k];
        }
        str_left[i] = 0;
        createBinTree(node->left,str_pre,str_left);
    }
    if(i<strlen(str_in)-1)
    {
        node->right = (PBinTreeNode)malloc(sizeof(BinTreeNode));
        char* str_right = (char*)malloc(sizeof(char) * (len - i)); //存放右子树序列
        for(int k=0;k<len-i-1;k++)
        {
            str_right[k] = str_in[k+i+1];
        }
        str_right[len-i-1] = '\0';
        createBinTree(node->right,str_pre,str_right);
    }

        
}
/* 后序输出
 * ptr_node,一个二叉树结节点指针
 * 通过后序方式递归输出
*/
void postOrderOutput(PBinTreeNode ptr_node){
	//后序遍历一棵二叉树 
	if(ptr_node->left){
		postOrderOutput(ptr_node->left);
	}
	if(ptr_node->right){
		postOrderOutput(ptr_node->right);
	}
	printf("%c",ptr_node->data);
}

/*
测试样例
ABDFGCEH
BFDGACEH
*/

西北工业大学NOJC程序设计习题答案(非本人制作,侵删) 1.“1“的传奇 2.A+B 3.A+BⅡ 4.AB 5.ACKERMAN 6.Arithmetic Progressions 7.Bee 8.Checksum algorithm 9.Coin Test 10.Dexter need help 11.Double 12.Easy problem 13.Favorite number 14.Graveyard 15.Hailstone 16.Hanoi Ⅱ 17.Houseboat 18.Music Composer 19.Redistribute wealth 20.Road trip 21.Scoring 22.Specialized Numbers 23.Sticks 24.Sum of Consecutive 25.Symmetric Sort 26.The Clock 27.The Ratio of gainers to losers 28.VOL大学乒乓球比赛 29.毕业设计论文打印 30.边沿与内芯的差 31.不会吧,又是A+B 32.不屈的小蜗 33.操场训练 34.插入链表节点 35.插入排序 36.插入字符 37.成绩表计算 38.成绩转换 39.出租车费 40.除法 41.创建与遍历职工链表 42.大数乘法 43.大数除法 44.大数加法 45.单词频次 46.迭代求根 47.多项式的猜想 48.二分查找 49.二分求根 50.发工资的日子 51.方差 52.分离单词 53.分数拆分 54.分数化小数 55.分数加减法 56.复数 57.高低交换 58.公园喷水器 59.韩信点兵 60.行程编码压缩算法 61.合并字符串 62.猴子分桃 63.火车站 64.获取指定二进制位 65.积分计算 66.级数和 67.计算A+B 68.计算PI 69.计算π 70.计算成绩 71.计算完全数 72.检测位图长宽 73.检查图像文件格式 74.奖金发放 75.阶乘合计 76.解不等式 77.精确幂乘 78.恐怖水母 79.快速排序 80.粒子裂变 81.链表动态增长或缩短 82.链表节点删除 83.两个整数之间所有的素数 84.路痴 85.冒泡排序 86.你会存钱吗 87.逆序整数 88.排列 89.排列分析 90.平均值函数 91.奇特的分数数列 92.求建筑高度 93.区间内素数 94.三点顺序 95.山迪的麻烦 96.删除字符 97.是该年的第几天 98.是该年的第几天? 99.数据加密 100.搜索字符 101.所有素数 102.探索合数世纪 103.特殊要求的字符串 104.特殊整数 105.完全数 106.王的对抗 107.危险的组合 108.文件比较 109.文章统计 110.五猴分桃 111.小型数据库 112.幸运儿 113.幸运数字”7“ 114.选择排序 115.寻找规律 116.循环移位 117.延伸的卡片 118.羊羊聚会 119.一维数组”赋值“ 120.一维数组”加法“ 121.勇闯天涯 122.右上角 123.右下角 124.圆及圆球等的相关计算 125.圆及圆球等相关计算 126.程序员添加行号 127.找出数字 128.找幸运数 129.找最大数 130.整数位数 131.重组字符串 132.子序列的和 133.子字符串替换 134.自然数立方的乐趣 135.字符串比较 136.字符串复制 137.字符串加密编码 138.字符串逆序 139.字符串排序 140.字符串替换 141.字符串左中右 142.组合数 143.最次方数 144.最大乘积 145.最大整数 146.最小整数 147.最长回文子串 148.左上角 149.左下角
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值