非递归法创建二叉树

简介: 非递归法创建二叉树

   问题分析:递归方法的创建二叉树,是基于系统栈的方式进行函数的调用,从而实现二叉树的创建。我们可以通过自己去构造栈的数据结构实现问题的解决。栈可以起到回溯的作用,使用先序遍历的插入,先一直往左子树插,当到了结束标志:本题中的 . 时开始回溯,往上一个的右子树插,同时可以在二叉链表中加入flag标记元素,方便代码对左右子树的判断。

要点:(1)灵活的运用栈的数据结构实现树内部的逻辑关系。(2)要设置特殊的二叉链表结构,多一个flag变量用来记录,如:flag=0左子树没有设置;flag=1左子树设置,右子树没有设置;flag=2出栈条件。(3)通常在没有重复结点的情况下,需要同时知道先序+中序,或者后序+中序才可以唯一确定一颗树(通过先序或后序确定根节点,通过中序判断左右子树),但是在本题中通过一个特殊的先序遍历,确定空结点的位置来确定唯一树。所以我们在定义一个树节点后,不要着急设置空树,根据 . 判断空树位置。

[问题描述]

任意给定一棵二叉树。试设计一个程序,在计算机中构造该二叉树,并对它进行遍历。要求:使用非递归算法的算法实现。

[输入]

一棵二叉树的结点若无子树,则可将其子树看作“.”,输入时,按照先序序列的顺序输入该结点的内容。对下图,其输入序列为ABD..EH...CF.I..G..,再输入数字K。

image.png

[输出]

 进行遍历后得到的序列

[存储结构]

采用二叉链表存储。

[算法的基本思想]

采用栈的存储结构实现非递归的方法先序序列创建二叉树,再使用队列的存储结构实现非递归的层次遍历

#include<stdio.h>
#include<malloc.h>
#define NULL 0
#define MAXSIZE 10
typedef struct BTNode{
  char a;
  int flag; //flag=0左子树没有设置;flag=1左子树设置,右子树没有设置;flag=2出栈条件 
  struct BTNode *lchild;
  struct BTNode *rchild;
}BTNode, *node;
node createBTNode(node p){
  //创建二叉树,非递归算法 
  BTNode *stack[MAXSIZE];  //定义栈 
  int top = -1;  //初始化栈
  p = (node)malloc(sizeof(BTNode));  //创建根节点 
  char x;
  scanf("%c", &x);
  p->a = x;
  p->flag = 0;
  stack[++top] = p;  //根结点进栈 
  while(top != -1){
    char x;
    scanf("%c", &x);
    if(x == '.'){
      //“.”空结点的表示方式 
      if(stack[top]->flag == 0){
        stack[top]->flag = 1;
        stack[top]->lchild = NULL;
      }
      else if(stack[top]->flag == 1){
        stack[top]->flag = 2;
        stack[top]->rchild = NULL;
      }
    }
    else{
      node q = (node)malloc(sizeof(BTNode));
      q->a = x;
      q->flag = 0;
      if(stack[top]->flag == 0){
        //先插左子树 
        stack[top]->lchild = q;
        stack[top]->flag = 1;
        stack[++top] = q;
      }
      else if(stack[top]->flag == 1){
        //判断是否满足插入右子树的条件 
        stack[top]->rchild = q;
        stack[top]->flag = 2;
        stack[++top] = q;
      }
    }
    while(stack[top]->flag == 2){
      //判断是否满足出栈条件,满足则连续出栈 
      top--;
    }
  }
  return p;
}
void showBTNode(node p){
  //使用非递归,层次遍历进行实现
  BTNode *queue[MAXSIZE];
  int front = 0;
  int rear = 0;
  queue[rear++] = p; //根结点入队 
  while(front != rear){
    if(queue[front]->lchild != NULL){
      queue[rear++] = queue[front]->lchild;
    }
    if(queue[front]->rchild != NULL){
      queue[rear++] = queue[front]->rchild;
    }
    printf("%c", queue[front]->a);
    front++;
  }
} 
int main(){
  node p = createBTNode(p);
  printf("层次遍历结果为:"); 
  showBTNode(p);
}

结构演示:

image.png

目录
相关文章
|
Linux 数据安全/隐私保护 Windows
Linux vsFTPd服务详解——本地用户登录实战
Linux vsFTPd服务详解——本地用户登录实战
787 2
|
Linux
Debian 11 / Deepin 20安装新版中文输入法fcitx5 / 搜狗拼音
Debian 11 / Deepin 20安装新版中文输入法fcitx5 / 搜狗拼音
8995 0
|
Java Linux Windows
java 图片上绘制文字Graphics2D linux 中文乱码
java 图片上绘制文字Graphics2D linux 中文乱码
910 0
|
JSON 前端开发 Java
SpringMVC系列(二)之常用注解介绍及参数传递说明
SpringMVC系列(二)之常用注解介绍及参数传递说明
|
NoSQL 算法 Java
【工具类用法】Hutool里的生成唯一Id唯的工具类
【工具类用法】Hutool里的生成唯一Id唯的工具类
1857 0
|
存储 关系型数据库 Linux
PostgreSQL命令行安装【静默安装】的全部流程
想要实现通过GUI软件一键安装PostgreSQL的功能,免去手动安装的过程,也可以添加一些对pgsql服务的管理功能。 这就要用到PostgreSQL通过命令行静默安装,放在软件中实现控制...
3211 0
PostgreSQL命令行安装【静默安装】的全部流程
|
消息中间件 运维 Serverless
商业版vs开源版:一图看懂云消息队列 RocketMQ 版核心优势
自建开源 RocketMQ 集群,为保证业务稳定性,往往需要按照业务请求的峰值去配置集群资源。云消息队列 RocketMQ 版 Serverless 实例通过资源快速伸缩,实现资源使用量与实际业务负载贴近,并按实际使用量计费,有效降低企业的运维压力和使用成本。
1192 136
|
11月前
|
传感器 人工智能 供应链
RFID助力畜牧养殖从个体溯源到全链管理的变革
RFID技术通过电子耳标、脚环等载体,实现畜禽个体精准识别与全生命周期管理,广泛应用于身份建档、智能饲喂、疫病预警、溯源监管及设备管控,推动畜牧养殖向智能化、数据化转型,助力降本增效、保障食品安全。
|
10月前
|
存储
观海微电子--常用电子元器件--电容
电容是由两导体及绝缘介质构成的储能元件,用于滤波、耦合、隔直等电路。单位为法拉,常见有μF、nF、pF。分贴片、钽、铝电解等类型,有极性区分。串联并联公式不同,需注意额定电压与温度特性,广泛应用于电子设备中。
|
存储 开发框架 安全
SpringCloud微服务实战——搭建企业级开发框架(四十):使用Spring Security OAuth2实现单点登录(SSO)系统
目前每家企业或者平台都存在不止一套系统,由于历史原因每套系统采购于不同厂商,所以系统间都是相互独立的,都有自己的用户鉴权认证体系,当用户进行登录系统时,不得不记住每套系统的用户名密码,同时,管理员也需要为同一个用户设置多套系统登录账号,这对系统的使用者来说显然是不方便的。我们期望的是如果存在多个系统,只需要登录一次就可以访问多个系统,只需要在其中一个系统执行注销登录操作,则所有的系统都注销登录,无需重复操作,这就是单点登录(Single Sign On 简称SSO)系统实现的功能。
1457 54
SpringCloud微服务实战——搭建企业级开发框架(四十):使用Spring Security OAuth2实现单点登录(SSO)系统

热门文章

最新文章