二叉树中用到的基本算法(叶子,度,遍历)

简介: 二叉树是数据结构中比较有意思的部分 二叉树有两种存储形式 1: 线性表 2:指针 其实链表是很重要的,二叉树就可以看为多条链表组合在一块。 在这里主要是指针来实现的。

二叉树是数据结构中比较有意思的部分
二叉树有两种存储形式
1: 线性表
2:指针

其实链表是很重要的,二叉树就可以看为多条链表组合在一块。
在这里主要是指针来实现的。 这里基本的算法都用到了递归实现

那在二叉树 中重要的算法如下:
a:创建一个二叉树(采用前序,活着中序,活着后序)
b:遍历二叉树(前序,中序,后序)
c:叶子结点的个数
d:树的高度
e:度为一的节点数
f:度为二的节点数
g:有分枝的节点数
h:查找某个节点

可能刚开始不能理解递归,找一个二叉树的图像,根据程序走一遍就基本能理解。


img_a47816174cf34c9e53ef52f7395653ab.png

那这个二叉树的前序遍历为。fcadbehgm
中序遍历为:acbdfehmg
后序遍历为:abdchmgef


//
// main.cpp
// 二叉树,中序遍历
//
// Created by 刘小成 on 2018/10/20.
// Copyright © 2018 刘晨. All rights reserved.
//
include<iostream>
using namespace std;
typedef struct bitNode{
char data;
bitNode *lChild;
bitNode *rChild;
}bitNode;
class Tree{
private:
bitNode *head;
void creatBitNode(bitNode *& t);//创建一棵树
void orderBitNode(bitNode *t);//中序遍历
void inorderBitNode(bitNode *t);//后序遍历
int countLeaf(bitNode *t);//叶子数量
int heightBitNodeTree(bitNode *t);//树高
int oneBitNode(bitNode *t);//度为一 的节点
int twoBitNode(bitNode *t);//度为二的节点
int branchBitNode(bitNode *t);//有分枝的节点
public:
Tree(){head = NULL;}
void creatTree(){
    bitNode *temp;
    creatBitNode(temp);
    head = temp;
}
void orderTree(){
    bitNode *t = head;
    cout<<"后序遍历的结果是: \t";
    orderBitNode(t);
    cout<<endl;
}

void inorderTree(){
    bitNode *t = head;
    cout<<"中序遍历的结果是: \t";
    inorderBitNode(t);
    cout<<endl;
}
void countLeafTree(){
    bitNode *t = head;
    cout<<"叶子节点的个数是:\t"<< countLeaf(t)<<endl;
}
void heightTree(){
    bitNode *t = head;
   cout<<"树的高度是:\t"<< heightBitNodeTree(t)<<endl;
}
void oneBitNodeTree(){
    bitNode *t = head;
    cout<<"度为一的节点个数是:\t"<<oneBitNode(t)<<endl;
}
void twoBitNodeTree(){
    bitNode *t = head;
    cout<<"度为二的节点个数是:\t"<<twoBitNode(t)<<endl;
}
void branchTree(){
    bitNode *t = head;
    cout<<"有分枝的节点个数是:\t"<<branchBitNode(t)<<endl;
}
};
void Tree::creatBitNode(bitNode *&t){
char data;
cin>>data;
if(data == '.') t=NULL;
if(data != '.'){
t = new bitNode;
t->data = data;
creatBitNode(t->lChild);
creatBitNode(t->rChild);
}
}
void Tree::orderBitNode(bitNode *t){
if(t == NULL) return;
else {
orderBitNode(t->lChild);
orderBitNode(t->rChild);
cout<<t->data;
}
}
void Tree::inorderBitNode(bitNode *t){
if (t == NULL) return ;
if(t != NULL){
inorderBitNode(t->lChild);
cout<<t->data;
inorderBitNode(t->rChild);
}
}
int Tree::countLeaf(bitNode *t){
if(t == NULL) return 0;
else {
int m = countLeaf(t->lChild);
int n = countLeaf(t->rChild);
if( m+n == 0) return 1;
else return m+n;
}
}
int Tree::heightBitNodeTree(bitNode *t){
if(t == NULL) return 0;
else{
int m = 1+heightBitNodeTree(t->lChild);
int n = 1+heightBitNodeTree(t->rChild);
return m>n ? m:n;
}
}
int Tree::oneBitNode(bitNode *t){
if(t==NULL) return 0;
else {
if( (t->lChild !=NULL && t->rChild == NULL) || (t->lChild == NULL && t->rChild !=NULL) ){
int m = oneBitNode(t->lChild);
int n = oneBitNode(t->rChild);
return 1+m+n;
}
else{
int m = oneBitNode(t->lChild);
int n = oneBitNode(t->rChild);
return m+n;
}
}
}
int Tree::twoBitNode(bitNode *t){
if( t== NULL) return 0;
else{
if( t->lChild != NULL && t->rChild != NULL){
int m = twoBitNode(t->lChild);
int n = twoBitNode(t->rChild);
return 1+m+n;
}
else{
int m = twoBitNode(t->lChild);
int n = twoBitNode(t->rChild);
return m+n;
}
}
}
int Tree:: branchBitNode(bitNode *t){
if (t == NULL) return 0;
else{
    if(t->lChild != NULL || t->rChild != NULL){
        int m = branchBitNode(t->lChild);
        int n = branchBitNode(t->rChild);
        return 1+m+n;
    }
    else{
        int m = branchBitNode(t->lChild);
        int n = branchBitNode(t->rChild);
        return m+n;
    }
}
}
int main(int argc, const char * argv[]) {
cout<<"先序创建一棵树\t\t 用"."表示NULL \n";
cout<<"输入\n";
Tree a ;
a.creatTree();
a.inorderTree();
a.orderTree();
a.countLeafTree();
a.heightTree();
a.oneBitNodeTree();
a.twoBitNodeTree();
a.branchTree();
return 0;
}

在私有方法里面创建递归函数,在公有函数里面调用递归函数。这样做的目的是不会产生多余的变量,变量连接紧密。

在创建递归函数的时候要考虑好函数的出口,好让函数可以返回。然后就要考虑递归函数里面递归的内容,将问题细小化。比如在统计叶子结点有多少个,
那函数的出口就是 这个节点是不是为空,若是空 ,就返回,
函数的递归内容就是。 对一个节点来说,先统计一个它的左子树的节点,在统计一下右子树的节点, 如果两边都是0,那他就是叶子结点,那就叶子结点,返回1,否则就不是叶子结点, 那就返回这个树的左边叶子结点数+右边的节点数。

那在对于树的高度函数来讲

img_50f5a2b07a168c2226b6b5db81a98931.png
image.png

在创建二叉树的时候要规定一个输入值,当这个值输入的时候那他就NULL。在上面中 作者规定的是“.”,

二叉的这些算法中对于递归的要求比较高。

那对于二叉树的度为一的节点的递归函数思想如下:

img_af60d0b0010211f5d1c1a19acc14d840.png
image.png

那度为二的节点其实和上面的思路是一样的。还有有分枝的节点。

相关文章
|
13天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
17天前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
42 5
|
17天前
|
算法
树的遍历算法有哪些?
不同的遍历算法适用于不同的应用场景。深度优先搜索常用于搜索、路径查找等问题;广度优先搜索则在图的最短路径、层次相关的问题中较为常用;而二叉搜索树的遍历在数据排序、查找等方面有重要应用。
22 2
|
20天前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
24 0
|
1月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
24 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
1月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
26 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
1月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
27 0
|
1月前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
9天前
|
算法 数据安全/隐私保护 索引
OFDM系统PAPR算法的MATLAB仿真,对比SLM,PTS以及CAF,对比不同傅里叶变换长度
本项目展示了在MATLAB 2022a环境下,通过选择映射(SLM)与相位截断星座图(PTS)技术有效降低OFDM系统中PAPR的算法实现。包括无水印的算法运行效果预览、核心程序及详尽的中文注释,附带操作步骤视频,适合研究与教学使用。
|
16天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
下一篇
无影云桌面