树低级(C语言版)

news/2024/11/13 4:26:58/

一.树基本计算规则

关于树的大部分知识点我们都讲过了,那么如果我给你树的节点,你可以算出叶子节点个数吗?

下面我们总结下一些计算规则:

1.父子计算规则:

parent=(child-1)/2;

leftchild=parent*2+1,rightchild=parent*2+2;

2.若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)个节点

3.深度为h的二叉树的最大结点数是2^h-1;

4. 对任何一棵二叉树, 如果度为0其叶结点个数为N0 , 度为2的分支结点个数为N2 ,则有

N0=N2+1
5. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h=log(n+1)  (log以2 为底,n+1为对数)
例题一:
1. 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为
A 不存在这样的二叉树
B 200
C 198
D 199
规则4,结果为200个,即B
如果不知道规则,那么就可能浪费不必要的时间,大家可以自行去找其他题目。

二.层序遍历

上次我们留下层序遍历没实现,现在我们学习树更近一步了,我们可以实现层序遍历了,在实现前让我们来看看下面两个概念:
深度优先遍历(Depth First Search):简称DFS,前序遍历,中序遍历和后序遍历都是,即一种 递归的遍历方式从一个起点开始,沿着一条路径一直走到底,直到不能再走为止,然后回溯到上一个节点,继续遍历其他路径,直到所有节点都被遍历过。
广度优先遍历(Breadth First Search):又称为广度优先搜索,简称BFS。是一种分层的查找过程,每向前走一步可能访问一批顶点,不像深度优先搜索那样有往回退的情况,因此它不是一个递归的算法。它是一个逐层遍历的过程,层序遍历就是BFS。
大家可能都经历过这样一个过程,就是使用QQ时,会推荐好友的好友,这其实就是一个广度优先遍历的实例。
下面回归我们主题:
如何去写层序遍历呢?
这个时候,是不是可以想到用队列,如果我们将树根放进队列,如果我们出队列,将树根的左右子序列放入,这样一直循环,是不是就可以做到层序遍历。
下面请看代码:
// 层序遍历定义(一:一起遍历)
void LevelOrder(TreeNode* root)
{Queue s1;QueueInit(&s1);//判断是否为空,不空的话,先压进一个if(root)QueuePush(&s1, root);while (!QueueEmpty(&s1)){TreeNode* cur = QueueFront(&s1);QueuePop(&s1);printf("%d ", cur->date);//压入它的左右孩子if(root->left)QueuePush(&s1, root->left);if (root->right)QueuePush(&s1, root->right);}printf("\n");
}

还是以这个树,我们检查一下:
//动态开辟空间定义
TreeNode* BuyTreeNode(int x)
{//开辟树的空间TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));assert(node);node->date = x;node->left = NULL;node->right = NULL;return node;
}
//建立二叉树定义
TreeNode* CreateTree()
{//开辟树并且对每个进行赋值TreeNode* node1 = BuyTreeNode(1);TreeNode* node2 = BuyTreeNode(2);TreeNode* node3 = BuyTreeNode(3);TreeNode* node4 = BuyTreeNode(4);TreeNode* node5 = BuyTreeNode(5);TreeNode* node6 = BuyTreeNode(6);//确定指向node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;return node1;
}
int main()
{TreeNode* root = CreateTree();LevelOrder(root);BinaryTreeDestory1(root);root = NULL;return 0;
}

结果:

是不是满足了层序遍历,好了,现在如果我让你将每层的结果,一行打印一层结果,该如何写呢?
// 层序遍历定义(二:逐层遍历)
void LevelOrder2(TreeNode* root)
{Queue s1;QueueInit(&s1);int size = 1;//判断是否为空,不空的话,先压进一个if (root != NULL)QueuePush(&s1, root);while (!QueueEmpty(&s1)){while (size>0){TreeNode* cur = QueueFront(&s1);QueuePop(&s1);printf("%d ", cur->date);//压入它的左右孩子if (cur->left)QueuePush(&s1, cur->left);if (cur->right)QueuePush(&s1, cur->right);size--;}printf("\n");size = QueueSize(&s1);}printf("\n");
}

结果:(还是上面的树)

三.判断二叉树是否是完全二叉树

判断一棵树是不是完全二叉树,我们还是可以利用栈来实现,这里很好理解,就直接展示代码了,里面都有注释。
//判断二叉树是否是完全二叉树
bool BinaryTreeComplete(TreeNode* root)
{Queue s1;QueueInit(&s1);//判断是否为空,不空的话,先压进一个if (root != NULL)QueuePush(&s1, root);//找到第一个空while (!QueueEmpty(&s1)){TreeNode* cur = QueueFront(&s1);QueuePop(&s1);if (cur == NULL)break;//压入它的左右孩子,注意:不用判断了		QueuePush(&s1, cur->left);QueuePush(&s1, cur->right);		}//第二步:如果在栈中还有非空,就说明不是完全二叉树//定理:如果不是完全二叉树,那么栈里面此时一定有数据了while (!QueueEmpty(&s1)){TreeNode* cur2 = QueueFront(&s1);QueuePop(&s1);if (cur2 != NULL)return false;}return true;
}

检查:

//建立二叉树定义
TreeNode* CreateTree()
{//开辟树并且对每个进行赋值TreeNode* node1 = BuyTreeNode(1);TreeNode* node2 = BuyTreeNode(2);TreeNode* node3 = BuyTreeNode(3);TreeNode* node4 = BuyTreeNode(4);TreeNode* node5 = BuyTreeNode(5);TreeNode* node6 = BuyTreeNode(6);TreeNode* node7 = BuyTreeNode(7);//确定指向node1->left = node2;node1->right = node4;node2->left = node3;node2->right = node7;node4->left = node5;//node3->left = node5;node4->right = node6;return node1;
}

对于这棵树结果为:
当然,你也可以自己去检查我的结果
对于树的中等部分就补充到这里了,后面我们还会讲一些高级的树,元旦快乐,bye!!!

http://www.ppmy.cn/news/1287117.html

相关文章

Termius for Mac/Win:一站式终端模拟器、SSH 和 SFTP 客户端软件的卓越选择

随着远程工作和云技术的普及,对于高效安全的远程访问和管理服务器变得至关重要。Termius,一款强大且易用的终端模拟器、SSH 和 SFTP 客户端软件,正是满足这一需求的理想选择。 Termius 提供了一站式的解决方案,允许用户通过单一平…

【Go语言入门:Go语言的数据结构】

文章目录 3.Go语言的数据结构:3.1. 指针3.2. struct(结构体)3.3. Map(映射,哈希) 3.Go语言的数据结构: 简介: 在Go语言中,数据结构体可以分为四种类型:基础类型、聚合类型、引用类型…

万字盘点 Android 领域在 2023 年的重要技术:AI, 14, Compose, 鸿蒙...

AICore 2022 年底横空出世的 GPT-3.5 引发了全球的大模型 LLM 狂潮。作为在 AI 领域耕耘多年的巨头,Google 自然不会坐视不管,于 2023 年底之际发布了超越 GPT-4 的 Gemini 系列模型,其在多模态领域的表现令无数人震撼。 而对于 Android 开发…

《每天十分钟》-红宝书第4版-执行上下文与作用域

先阅读一段晦涩难懂的文字 执行上下文(以下简称“上下文”)的概念在 JavaScript 中是颇为重要的。变量或函数的上下文决定 了它们可以访问哪些数据,以及它们的行为。每个上下文都有一个关联的变量对象(variable object&#xff09…

编程笔记 html5cssjs 011 HTML页面划分

编程笔记 html5&css&js 011 HTML页面划分 HTML的框架、区块和布局是什么,它们之前的关系是怎样的?框架注意 接下来要看一下网页内的划分。通过框架、区块及布局等方式,将网页从一个长方形整体划分为若干个部分,以合理展示…

【elk-day01】es和kibana搭建及验证---Mac-Docker

Mac系统使用Docker下载搭建和验证eskibana Docker下载安装es安装es验证kibana安装kibana验证 Docker下载安装 Docker Desktop官网安装下载地址 说明一下为什么要安装desktop版本的docker,因为docker作为工具使用,我们需要的是开箱即用,没有必…

WPF 消息日志打印帮助类:HandyControl+NLog+彩色控制台打印+全局异常捕捉

文章目录 前言相关文章Nlog配置HandyControl配置简单使用显示效果文本内容 全局异常捕捉异常代码运行结果 前言 我将简单的HandyControl的消息打印系统和Nlog搭配使用,简化我们的代码书写 相关文章 .NET 控制台NLog 使用 WPF-UI HandyControl 控件简单实战 C#更改…

用linux中定时任务Crontab,向企业微信群通过机器人发送消息

1.使用yum命令安装Crontab:这个很关键,没有安装的话会提示命令not found yum install vixie-cron yum install crontabs 注:vixie-cron软件包是cron的主程序; crontabs软件包是用来安装、卸装、或列举用来驱动 cron 守护进程的表…