非递归法创建二叉树

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

   问题分析:递归方法的创建二叉树,是基于系统栈的方式进行函数的调用,从而实现二叉树的创建。我们可以通过自己去构造栈的数据结构实现问题的解决。栈可以起到回溯的作用,使用先序遍历的插入,先一直往左子树插,当到了结束标志:本题中的 . 时开始回溯,往上一个的右子树插,同时可以在二叉链表中加入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服务详解——本地用户登录实战
508 2
|
Linux
Debian 11 / Deepin 20安装新版中文输入法fcitx5 / 搜狗拼音
Debian 11 / Deepin 20安装新版中文输入法fcitx5 / 搜狗拼音
7525 0
|
2月前
|
传感器 人工智能 供应链
RFID助力畜牧养殖从个体溯源到全链管理的变革
RFID技术通过电子耳标、脚环等载体,实现畜禽个体精准识别与全生命周期管理,广泛应用于身份建档、智能饲喂、疫病预警、溯源监管及设备管控,推动畜牧养殖向智能化、数据化转型,助力降本增效、保障食品安全。
|
消息中间件 运维 Serverless
商业版vs开源版:一图看懂云消息队列 RocketMQ 版核心优势
自建开源 RocketMQ 集群,为保证业务稳定性,往往需要按照业务请求的峰值去配置集群资源。云消息队列 RocketMQ 版 Serverless 实例通过资源快速伸缩,实现资源使用量与实际业务负载贴近,并按实际使用量计费,有效降低企业的运维压力和使用成本。
812 103
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
存储 关系型数据库 MySQL
【MYSQL】 ——索引(B树B+树)、设计栈
索引的特点,使用场景,操作,底层结构,B树B+树,MYSQL设计栈
|
存储 关系型数据库 MySQL
MySQL主从复制原理和使用
本文介绍了MySQL主从复制的基本概念、原理及其实现方法,详细讲解了一主两从的架构设计,以及三种常见的复制模式(全同步、异步、半同步)的特点与适用场景。此外,文章还提供了Spring Boot环境下配置主从复制的具体代码示例,包括数据源配置、上下文切换、路由实现及切面编程等内容,帮助读者理解如何在实际项目中实现数据库的读写分离。
1523 1
MySQL主从复制原理和使用
|
存储 开发框架 安全
SpringCloud微服务实战——搭建企业级开发框架(四十):使用Spring Security OAuth2实现单点登录(SSO)系统
目前每家企业或者平台都存在不止一套系统,由于历史原因每套系统采购于不同厂商,所以系统间都是相互独立的,都有自己的用户鉴权认证体系,当用户进行登录系统时,不得不记住每套系统的用户名密码,同时,管理员也需要为同一个用户设置多套系统登录账号,这对系统的使用者来说显然是不方便的。我们期望的是如果存在多个系统,只需要登录一次就可以访问多个系统,只需要在其中一个系统执行注销登录操作,则所有的系统都注销登录,无需重复操作,这就是单点登录(Single Sign On 简称SSO)系统实现的功能。
1196 54
SpringCloud微服务实战——搭建企业级开发框架(四十):使用Spring Security OAuth2实现单点登录(SSO)系统
|
编解码 移动开发 前端开发
详细介绍Viewport Meta标签的作用、属性以及如何在移动端开发中合理使用它,以优化网页的显示效果
【6月更文挑战第14天】本文介绍了HTML的Viewport Meta标签在移动端网页优化中的应用。该标签定义了视口属性,如宽度、高度和缩放,解决屏幕尺寸差异导致的显示问题。通过设置`width=device-width`确保页面适应设备宽度,`initial-scale=1.0`保持原始比例,`user-scalable=no`可禁用手动缩放。此外,使用`viewport-fit=cover`适配不同像素比设备的安全区域。合理利用这些属性能改善移动端网页显示效果。
763 1
|
编解码 定位技术 Python
Google Earth Engine谷歌地球引擎GEE批量下载ImageCollection遥感影像数据合集的方法
Google Earth Engine谷歌地球引擎GEE批量下载ImageCollection遥感影像数据合集的方法
957 2