第十周 【项目1 - 二叉树构造算法的验证(2)】_lilinxi_的博客-程序员秘密

/*      
* Copyright(c) 2017,烟台大学计算机学院      
* All rights reserved.      
* 作    者:李琳汐      
* 完成日期:2017 年 11 月 16日      
* 版 本 号:v1.0      
*      
* 问题描述:二叉树的构造
*/            

1.由先序序列和中序序列构造二叉树

  • 定理:任何n(n≥0)个不同节点的二叉树,都可由它的中序序列和先序序列唯一地确定。
  • 证明(数学归纳法) 
    基础:当n=0时,二叉树为空,结论正确。 
    假设:设节点数小于n的任何二叉树,都可以由其先序序列和中序序列唯一地确定。 
    归纳:已知某棵二叉树具有n(n>0)个不同节点,其先序序列是 a0a1an1 ;中序序列是 b0b1bk1bkbk+1bn1 。 
    • 先序遍历“根-左-右”, a0 必定是二叉树的根节点
    • a0 必然在中序序列中出现,设在中序序列中必有某个 bk0kn1 就是根节点 a0 。 
      这里写图片描述
    • 由于 bk 是根节点,中序遍历“左-根-右”,故中序序列中 b0b1bk1 必是根节点 bk(a0) 左子树的中序序列,即 bk 的左子树有k个节点, bk+1bn1 必是根节点 bka0 右子树的中序序列,即 bk 的右子树有 nk1 个节点。
    • 对应先序序列,紧跟在根节点 a0 之后的k个节点 a1ak 是左子树的先序序列, ak+1an1 nk1 就是右子树的先序序列。 
      这里写图片描述
    • 根据归纳假设,子先序序列 a1ak 和子中序序列 b0b1bk1 可以唯一地确定根节点 a0 的左子树,而先序序列 ak+1an1 和子中序序列 bk+1bn1 可以唯一地确定根节点 a0 的右子树。
    • 综上所述,这棵二叉树的根节点己经确定,而且其左、右子树都唯一地确定了,所以整个二叉树也就唯一地确定了。
  • 例 
    这里写图片描述

    根据定理的证明,写出下面的算法。

#include <stdio.h>
#include <malloc.h>
#include "btree.h"

BTNode *CreateBT1(char *pre,char *in,int n)
/*pre存放先序序列,in存放中序序列,n为二叉树结点个数,
本算法执行后返回构造的二叉链的根结点指针*/
{
    BTNode *s;
    char *p;
    int k;
    if (n<=0) return NULL;
    s=(BTNode *)malloc(sizeof(BTNode));     //创建二叉树结点*s
    s->data=*pre;
    for (p=in; p<in+n; p++)                 //在中序序列中找等于*ppos的位置k
        if (*p==*pre)                       //pre指向根结点
            break;                          //在in中找到后退出循环
    k=p-in;                                 //确定根结点在in中的位置
    s->lchild=CreateBT1(pre+1,in,k);        //递归构造左子树
    s->rchild=CreateBT1(pre+k+1,p+1,n-k-1); //递归构造右子树
    return s;
}

int main()
{
    ElemType pre[]="ABDGCEF",in[]="DGBAECF";
    BTNode *b1;
    b1=CreateBT1(pre,in,7);
    printf("b1:");
    DispBTNode(b1);
    printf("\n");
    return 0;
}

运行结果:


2.由后序序列和中序序列构造二叉树

  • 定理:任何n(n>0)个不同节点的二叉树,都可由它的中序序列和后序序列唯一地确定。
  • 证明:(略) 
    这里写图片描述
#include <stdio.h>
#include <malloc.h>
#include "btree.h"

BTNode *CreateBT2(char *post,char *in,int n)
/*post存放后序序列,in存放中序序列,n为二叉树结点个数,
本算法执行后返回构造的二叉链的根结点指针*/
{
    BTNode *s;
    char r,*p;
    int k;
    if (n<=0) return NULL;
    r=*(post+n-1);                          //根结点值
    s=(BTNode *)malloc(sizeof(BTNode));     //创建二叉树结点*s
    s->data=r;
    for (p=in; p<in+n; p++)                 //在in中查找根结点
        if (*p==r)
            break;
    k=p-in;                                 //k为根结点在in中的下标
    s->lchild=CreateBT2(post,in,k);         //递归构造左子树
    s->rchild=CreateBT2(post+k,p+1,n-k-1);  //递归构造右子树
    return s;
}

int main()
{
    ElemType in[]="DGBAECF",post[]="GDBEFCA";
    BTNode *b2;
    b2=CreateBT2(post,in,7);
    printf("b2:");
    DispBTNode(b2);
    printf("\n");
    return 0;
}

运行结果:


3.由顺序存储结构转为二叉链存储结构 
这里写图片描述
#include <stdio.h>
#include <malloc.h>
#include "btree.h"
#define N 30
typedef ElemType SqBTree[N];
BTNode *trans(SqBTree a,int i)
{
    BTNode *b;
    if (i>N)
        return(NULL);
    if (a[i]=='#')
        return(NULL);           //当节点不存在时返回NULL
    b=(BTNode *)malloc(sizeof(BTNode)); //创建根节点
    b->data=a[i];
    b->lchild=trans(a,2*i);                 //递归创建左子树
    b->rchild=trans(a,2*i+1);               //递归创建右子树
    return(b);                              //返回根节点
}
int main()
{
    BTNode *b;
    ElemType s[]="0ABCD#EF#G####################";
    b=trans(s,1);
    printf("b:");
    DispBTNode(b);
    printf("\n");
    return 0;
}

运行结果:


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lilinxi_/article/details/78662463

智能推荐

PSPNet《Pyramid Scene Parsing Network》论文阅读及代码实现_just_sort的博客-程序员秘密

论文原文https://arxiv.org/abs/1612.01105摘要\quad本文提出的金字塔池化模块( pyramid pooling module)能够聚合不同区域的上下文信息,从而提高获取全局信息的能力。实验表明这样的先验表示(即指代PSP这个结构)是有效的,在多个数据集上展现了优良的效果。介绍\quad场景解析(Scene Parsing)的难度与场景的标签密切相关。先大...

Java基础--集合类_「已注销」的博客-程序员秘密

最近在找工作,目前还没有定下来,拿到了一个公司的offer,不过被当白菜了,正在商量薪资方面的事情。随着百度面试的失败,梦想再次破灭。想想这一年来的奋斗,别是一番滋味在心头。突然想起一句话:踏歌长行,梦想永在!说程序员是幸福的,因为我们每天都会和大脑过意不去,故意去挑战,因为我们总是在与IDE经历了一系列的战斗后,露出欣喜的表情,也因为我们总是以自己从事复杂的、高智商的工作而骄傲、自豪!

Android Studio 包冲突的解决方法_投木报琼zh的博客-程序员秘密

Android Studio 中包冲突,即多个项目引用的相同的jar包1、cache.xml中查看那个那个项目下的jar包不一样,即定位是哪个jar包引起的冲突。cache.xml文件的路径:2、如果多个项目引用的相同的jar包,可以将jar包单独提出来,两个项目都依赖那个jar包:compile files('./../local_jar_files/XXX.jar')

hello world !_大二上学期忙吗_明天更好~\(≧▽≦)/~的博客-程序员秘密

# include &lt;stdio.h&gt;int main (void){ printf("hello world !\n"); return 0 ;}CodeBlock上面的运行结果:// 第一次见到这段代码是上一年疫情在家大一下学期的时候,现在看来还没有一年之久,第一次见它的时候,很懵。现在看来是那么的亲切。我决定把自己学习路上的点滴记录在CSDN上面,第一个一定就是hello world ! 了。上一学期,就是大二的上学期,又学习了数据结构,学校的教学几乎完

自动推送消息时附带图片的一种实现方式_AlbertS的博客-程序员秘密

本文是之前总结 使用的这篇文章 《借助第三方工具网站完成消息自动推送》 的后续,当时说使用pushplus的微信公众号渠道不允许直接发图片,但是可以将图片链接放到 image 标签中,这就要求我们必须要有一个图床,今天也是从这里开始...

随便推点

消息队列mq总结_普通网友的博客-程序员秘密

一、消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ 二、消息队列应用场景 ...

Go test 命令行参数_sas???的博客-程序员秘密

为什么80%的码农都做不了架构师?&gt;&gt;&gt; ...

2021 长城杯 pwn K1ng_in_h3Ap_I_pwn攻击stdout_yongbaoii的博客-程序员秘密

libc是2.23菜单addfree显然是有uaf。edit就是输入输入函数其实还有off by one。有个后门我们的思路就是简单的说因为有uaf但是没有show,所以我们就直接攻击stdout,但是又因为后门给了我们地址,所以就解决了爆破这个问题。然后就攻击IO_FILE泄露libc,再攻击malloc_hook就好啦。第一个exp是利用off by one来构造的。expfrom pwn import *r = process("./pwn1")context.a

Tomcat服务器配置https双向认证,使用JDK的keytool生成证书(适用于web、安卓、IOS)_tomcat keytool 证书_龙少玉的博客-程序员秘密

Tomcat服务器配置https双向认证,使用JDK的keytool生成证书(适用于web、安卓、IOS)一、原理1.HTTP:平时浏览网页时候使用的一种协议。HTTP协议传输的数据都是未加密的(明文),因此使用HTTP协议传输隐私信息非常不安全。2.HTTPS:为了保证隐私数据能加密传输,采用SSL/TLS协议用于对HTTP协议传输的数据进行加密,也就是HTTPS。二、说明1.原因:因...

最新kali之bulk_extractor_Vanony的博客-程序员秘密

描述:  扫描磁盘映像中的正则表达式和其他内容  bulk_extractor扫描磁盘映像(或任何其他文件),查找大量预定义的正则表达式和其他类型的内容。这些项称为特性。当它找到一个特性时,bulk_extractor将输出写到输出文件中。输出文件的每一行都包含发现特性所在的字节偏移量、制表符和实际特性。因此,功能部件不能包含行尾字符。  bulk_extractor包括对EnCase(.E01)和AFFLIB(.aff)文件的本机支持,如果它在包含这些库的系统上进行编译和链接的话。 另外,-R选项可

apache 2.2.13_webwindy的博客-程序员秘密

Changes with Apache 2.2.13  *) SECURITY: CVE-2009-2412 (cve.mitre.org)     Distributed with APR 1.3.8 and APR-util 1.3.9 to fix potential overflow     in pools and rmm, where size alignment was taki...

推荐文章

热门文章

相关标签