当前位置: 首页 > news >正文

二叉树基于队列实现的操作详解

一、队列知识补充

有关队列的知识请详见博主的另一篇博客:http://t.csdnimg.cn/3PwO4

本文仅仅附上需要的队列操作供读者参考

//结构体定义
typedef struct BinaryTreeNode* QDataType;typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;//入队
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = InitNewnode(x);if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
//出队
void QueuePop(Queue* pq)
{assert(pq);assert(pq->size != 0);if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* temp = pq->phead->next;free(pq->phead);pq->phead = temp;}pq->size--;
}
//取出队头元素
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}
//销毁队列
void QueueDestroy(Queue* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* temp = pcur->next;free(pcur);pcur = temp;}pq->phead = pq->ptail = NULL;pq->size = 0;
}

二、层序遍历

2.1 递归思路

采用队列先进先出的特点,按照层序入队即可按照层序出队,从而达到层序遍历的目的。

考虑一般情况:

将根节点入队,下一次根节点出队的同时将孩子结点入队。

考虑特殊情况:

孩子结点可看作子树的根节点,重复递归即可。

只要队列不为空就一直递归

2.2 图解

2.3 C语言实现

注意:出队入队要额外新建变量来复制结点,避免销毁队列引发的原二叉树丢失的问题。

void TreeLevelOrder(BTNode* root)
{Queue q;QueueInit(&q);if (root){QueuePush(&q, root);}while (QueueEmpty(&q)==false){BTNode* front = QueueFront(&q);QueuePop(&q);printf("%d ", front->data);if (front->left){QueuePush(&q, front->left);}if (front->right){QueuePush(&q, front->right);}}QueueDestroy(&q);
}

三、判断一棵树是不是完全二叉树

3.0 回顾

        什么是完全二叉树?完全二叉树是一种特殊的二叉树,其中除了最后一层外,每一层的节点都被填满,而且最后一层的节点都尽可能地靠左排列。换句话说,如果一个层次深度为k的树,除了第 k 层外,其他各层都是满的,并且第 k 层的节点都依次靠左排列,则这棵树就是完全二叉树。

        所以仅仅通过判断结点的范围处于k-1层满二叉树和k层满二叉树之间的解法是错误的!!       

3.1 思路

通过层序遍历,将第一次出现空结点的地方找到,只需判断后续遍历的过程中是否存在非空结点即可,若存在就不是完全二叉树,反之则是。

分两个循环解决该问题。

  1. 第一层循环本质即为层序遍历,找到第一个空节点就退出。
  2. 第二层循环依然为层序遍历,看是否可以找到非空结点。当队列里面没有元素即层序遍历结束时判断完成。

3.2 C语言实现

bool BinaryTreeComplete(BTNode* root)
{Queue q;QueueInit(&q);if (root != NULL){QueuePush(&q, root);}//入队遇到空停止入队while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);if (front == NULL){break;}QueuePush(&q, front->left);QueuePush(&q, front->right);}//判断后面是否还有非空while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);if (front != NULL){return false;}}QueueDestroy(&q);return true;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • python梯度下降法求解三元线性回归系数,并绘制结果
  • EyeMock下载与使用教程
  • 【C++项目】实时聊天的在线匹配五子棋对战游戏
  • in 和exists的区别
  • DHCP简介
  • 探索亚马逊云科技技术课程:大模型平台与提示工程的应用与优化
  • Virtuoso IC5141 实验七 两级运算放大器设计
  • 牛客NC367 第K个n的排列【困难 dfs,全排列问题 Java/Go/PHP/C++】
  • Study--Oracle-03-Oracle19C--RAC集群部署
  • 掌握C++回调:按值捕获、按引用捕获与弱引用
  • NB65 第k轻的牛牛
  • windows下nginx配置https证书
  • 无人机监测系统:天空之眼,精准掌握地球脉动
  • osgearth 3.5 vs 2019编译
  • 【LeetCode 随笔】面试经典 150 题【中等+困难】持续更新中。。。
  • 【剑指offer】让抽象问题具体化
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • Angular 4.x 动态创建组件
  • Fundebug计费标准解释:事件数是如何定义的?
  • Java教程_软件开发基础
  • JS专题之继承
  • Otto开发初探——微服务依赖管理新利器
  • Shell编程
  • Vue.js-Day01
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • Zsh 开发指南(第十四篇 文件读写)
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 好的网址,关于.net 4.0 ,vs 2010
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 深入浅出Node.js
  • 数组大概知多少
  • 一、python与pycharm的安装
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 最近的计划
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ### RabbitMQ五种工作模式:
  • #android不同版本废弃api,新api。
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • #知识分享#笔记#学习方法
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (C语言)fgets与fputs函数详解
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (八十八)VFL语言初步 - 实现布局
  • (二)JAVA使用POI操作excel
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (三分钟)速览传统边缘检测算子
  • (生成器)yield与(迭代器)generator
  • (四)js前端开发中设计模式之工厂方法模式
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world