目录

二叉树定义

二叉树图解

特殊的二叉树

二叉树的性质

二叉树的基本代码实现

二叉数的定义

二叉树的输入(创建)

二叉树的遍历

二叉树的深度优先遍历

二叉树的广度优先遍历

二叉树的基本功能函数的实现

返回宽度和深度

深度

宽度

返回节点个数

返回二度节点

返回一度节点

返回叶子节点(0度)

返回空节点(NULL)

二叉树基本特点函数的实现

翻转二叉树

二叉树性质的判断

完全二叉树

平衡二叉树

对称二叉树

单值二叉树


树的介绍

二叉树定义

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分。

二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点。

二叉树图解

特殊的二叉树

完全二叉树:

一棵深度为k的有n个结点的 二叉树 ,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与 满二叉树 中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。.

满二叉树:

一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。. 也就是说,如果一个二叉树的层数为K,且结点总数是 (2^k) -1 ,则它就是满二叉树。

二叉搜索树:

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的值; 若它的右子树不空,则右子树上所有结点的值均大于它的值

二叉平衡树(AVL):

平衡树(Balance Tree,BT) 指的是,任意节点的子树的高度差都小于等于1。常见的符合平衡树的有,B树(多路平衡搜索树)、AVL树(二叉平衡搜索树)等。

B树,B+树:

一棵m阶B树(balanced tree of order m)是一棵平衡的m路搜索树。它或者是空树,或者是满足下列性质的树:根结点至少有两个子女;每个非根节点所包含的关键字个数 j 满足:[m/2] - 1 <= j <= m - 1;除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树个数 k 满足:[m/2] <= k <= m ;所有的叶子结点都位于同一层。

红黑树:

红黑树是每个结点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求: 1.结点是红色或黑色;2.根结点是黑色;3. 所有叶子都是黑色(叶子是NIL结点);4. 每个红色结点的两个子结点都是黑色(从每个叶子到根的所有路径上不能有两个连续的红色结点);5. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。

二叉树的性质

(1):一颗非空二叉树的第n层最多有2^(n-1)个节点

(2):若一颗非空二叉树的深度为h,那么它最多能有2^h-1个节点

(3):具有N个节点的完全二叉树,它的深度h=ceil(㏒₂(N+1))ceil表示向上取整,例如ceil(2.23)=ceil(2.64)=ceil(3)=3

★(4):一颗二叉树,2度节点和叶子节点(度为0)满足以下关系:D₀=D₂+1 也就是说叶子节点个数始终等于二度节点个数加一

★(5):一颗二叉树,若他的节点个数是2n个,那么他的叶子节点个数为n个

二叉树的基本代码实现

二叉数的定义

二叉树通常采用孩子表示法,因此定义的代码为:

//定义二叉树
typedef struct BTNode {char data;//数据域BTNode* left;//指向左孩子节点BTNode* right;//指向右孩子节点
}BinaryTree;
/*该结构体有两个名字
分别翻译为节点(BTNode),二叉树(BinaryTree)加以区分
*/

二叉树的输入(创建)

由于二叉树是一对多结构,我们无法得知某某数据,它具体是谁的孩子节点,因此使得它不能像链表这样循环输入,而只能递归回溯输入。

所以涉及到回溯算法

★★★二叉树包含大量的回溯算法

回溯算法初步介绍

回溯算法,又称为“试探法”。解决问题时,每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,或者这么走下去肯定达不到目标,立刻做回退操作重新选择。这种走不通就回退再走的方法就是回溯算法。

二叉树创建代码:

//创建二叉树
void  BTCreate(BinaryTree* &root) {BTNode *q; //创建新节点q=new BTNode;//初始化节点,相当于malloc函数cin>>q->data;//输入数据if(q->data=='#') {//判断是否为'#"root=q=NULL; //若是,则设置虚拟节点q,并接到二叉树上return; //返回上一个节点}root=q; //若否,则将节点q接在二叉数上BTCreate(root->left); //进入左孩子BTCreate(root->right); //进入右孩子return; //返回上一个节点
}

二叉树创建图解

  

以上就是二叉树:ABC##D###的创建过程。

主要还是回溯算法,当创建了空节点的时候,就回溯返回上一个节点,不再递归分治。

二叉树的遍历

二叉树的深度优先遍历

前序遍历,又叫先根遍历。遍历顺序:根 - > 左孩子 - >右孩子。

//前序遍历
void BTProOrder(BinaryTree* &root) {if(root==NULL) return;cout<<root->data<<" ";BTProOrder(root->left);BTProOrder(root->right);
}

中序遍历,又叫中根遍历。遍历顺序:左孩子 -> 根 -> 右孩子

//中序遍历
void BTInOrder(BinaryTree* &root) {if(root==NULL) return;BTInOrder(root->left);cout<<root->data<<" ";BTPostOrder(root->right);
}

后序遍历,又叫后根遍历。遍历顺序:左孩子 -> 右孩子 -> 根

//后序遍历
void BTPostOrder(BinaryTree* &root) {if(root==NULL) return;BTPostOrder(root->left);BTPostOrder(root->right);cout<<root->data<<" ";
}

二叉树的广度优先遍历

层序遍历。顾名思义,就是按照树的层次,从第1层到第n层,从上到下,从左到右进行遍历输出。

像这样,就是层序遍历。

//层序遍历
void BTLevelOrder(BinaryTree* &root) {queue<BinaryTree*>Q;Q.push(root);BTNode *q;while(!Q.empty()) {cout<<Q.front()->data;q=Q.front();Q.pop();if(q->left!=NULL) Q.push(q->left);if(q->right!=NULL) Q.push(q->right);}
}

二叉树的基本功能函数的实现

返回宽度和深度

深度

返回深度介绍

int Height(BinaryTree* &root) {if(root==NULL) return 0;else return max(Height(root->left),Height(root->right))+1;//左子树或者右子树的最大值
}//max(a,b):返回a,b的最大值

宽度

返回宽度介绍

int a[10005];//数组a表示储存第key层有几个节点
//key表示第几层,刚开始key为1,也就是第一层
//ans表示最终答案
void Wide(BinaryTree* &root,int key,int &ans) {if(root==NULL) return;else {a[key]++;ans=max(ans,a[key]);Wide(root->left,key+1,ans);Wide(root->right,key+1,ans);}
}

返回节点个数

返回二度节点

int node_two(BinaryTree* &root) {if(root==NULL) return 0;//同时搜索左右孩子节点//当左右孩子节点都不为空,说明是2度节点,值加一if(root->left!=NULL&&root->right!=NULL) return node_two(root->left)+node_two(root->right)+1;//否则直接搜索else return node_two(root->left)+node_two(root->right);
}

返回一度节点

int node_one(BinaryTree* &root) {if(root==NULL) return 0;//同时搜素左右孩子节点//当左右孩子节点有一个不为空,一个为空,说明是1度节点,值加一if(root->left!=NULL&&root->right==NULL || root->right!=NULL&&root->left==NULL) return node_one(root->left)+node_one(root->right)+1;//否则直接搜索else return node_one(root->left)+node_one(root->right);
}

返回叶子节点(0度)

int node_zero(BinaryTree* &root) {if(root==NULL) return 0;//同时搜素左右孩子节点//当左右孩子节点都为空,说明是0度节点,返回1if(root->left==NULL && root->right==NULL) return 1;//否则直接搜索else return node_zero(root->left)+node_zero(root->right);
}

返回空节点(NULL)

int node_NULL(BinaryTree* &root) {//当该节点为空,返回1if(root=NULL) return 1;//否则搜索左右孩子else return node_NULL(root->left)+node_NULL(root->right);
}

二叉树基本特点函数的实现

翻转二叉树

翻转二叉树可以先镜面先序遍历(根->右孩子->左孩子),并储存。然后再依次先序创建之前储存的镜面先序遍历。

//创建翻转二叉树
char node[10005];
int sum2=0;
void create(BinaryTree* &root) {BTNode *q;q=new BTNode;q->data=node[sum2++];if(q->data=='#') {root=q=NULL;return;}root=q;create(root->left);create(root->right);
}
//镜面先序遍历
int sum1=0;
void sy_BTProOrder(BinaryTree* &root) {if(root==NULL) {node[sum1++]='#';return;}node[sum1++]=root->data;sy_BTProOrder(root->right);sy_BTProOrder(root->left);
}

二叉树性质的判断

完全二叉树

判断是否为完全二叉树,根据定义,和宽度优先遍历(层序遍历)有点类似

bool isCompleteTree(BinaryTree* &root) {queue<BinaryTree*>Q;Q.push(root);  BTNode *q;while(!Q.empty()) {if(Q.front()==NULL) break;q=Q.front();Q.pop();Q.push(q->left);Q.push(q->right);}while(!Q.empty()) {if(Q.front()!=NULL) return false;Q.pop();}return true;
}

平衡二叉树

根据定义,判断左右子树深度的绝对值之差,若不大于1,并且左右子树也为平衡二叉树,则该树为平衡二叉树。

//求二叉树深度
int depth(BinaryTree* &root) {if(root==NULL) return 0;else return max(depth(root->left),depth(root->right))+1;
}
//判断是否为平衡二叉树
bool isBalanced(BinaryTree* &root) {if(root==NULL) return true;int leftDepth=depth(root->left);int rightDepth=depth(root->right);if(abs(leftDepth-rightDepth)>1) return false;//判断左右子树是否也为平衡二叉树return isBalanced(root->left) && isBalanced(root->right);
}

对称二叉树

就像照镜子一样,从根开始。整两个遍历轴,一个往左遍历,一个往右遍历,形成镜面对称。

若其中有不同,那么结束遍历,返回false。

//两个遍历轴,遍历函数
bool symmetry(BinaryTree* &rootL,BinaryTree* &rootR) {if(rootL==NULL&&rootR==NULL) return true;if(rootL==NULL||rootR==NULL) return false;if(rootL->data!=rootR->data) return false;else return (rootL->left,rootR->right) && (rootL->right,rootR->left);
}
//主判断函数
bool isSymmetryTree(BinaryTree* &root) {if(root==NULL) return true;return symmetry(root->left,root->right);
}

单值二叉树

单值二叉树是指所有节点的data都一样

bool isUnivalTree(BinaryTree* &root) {if(root==NULL) return true;if(root->data != root->left->data) return false;if(root->data != root->right->data) return false;return isUnivalTree(root->left) && isUnivalTree(root->right);
}

数据结构笔记(6)二叉树的实现相关推荐

  1. 数据结构笔记:二叉树的构造(根据遍历顺序构造二叉树)

    目录 给出先序遍历序列和中序遍历序列可以唯一确定二叉树 给出后序遍历序列和中序遍历序列可以唯一确定二叉树 题: 给出先序遍历序列和中序遍历序列可以唯一确定二叉树 给出后序遍历序列和中序遍历序列可以唯一 ...

  2. 数据结构笔记6: 二叉树和其他树

    树的一般定义 树 线性表.表:不适合描述层次结构数据 树(tree):是一个非空的有限元素的集合,其中有一个特殊的元素称为根,余下的元素组成树的若干子树 递归的思想:每棵树=根+若干棵子树,每棵子树= ...

  3. 数据结构笔记(王道考研) 第五章:树和二叉树

    大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,该课属于付费课程(不过盗版网盘资源也不难找...).后续又根据23年考研的大纲对内容做了一些调整,将二叉排序树和平衡二叉树的内容挪到 ...

  4. 数据结构笔记(王道考研) 第八章:排序

    大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,该课属于付费课程(不过盗版网盘资源也不难找...).后续又根据23年考研的大纲对内容做了一些调整,将二叉排序树和平衡二叉树的内容挪到 ...

  5. 一、考研数据结构笔记——引言及目录

    一.关于我理解的数据结构 1. 引言 本人自2021年3月准备考研,考研主要是为了提升学历,本科院校不是理想.迫切需要提高学历. 写这刊博客,主要是总结我考研路上对数据结构的一些理解,以及为了方便我后 ...

  6. 鸿钧老祖 数据结构笔记01:编程面试过程中常见的10大算法(java)

    以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java的角度看问题,包含下面的这些概念: ...

  7. 数据结构笔记(王道考研) 第一章:绪论

    大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,该课属于付费课程(不过盗版网盘资源也不难找...).后续又根据23年考研的大纲对内容做了一些调整,将二叉排序树和平衡二叉树的内容挪到 ...

  8. 数据结构笔记(王道考研) 第七章:查找

    大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,该课属于付费课程(不过盗版网盘资源也不难找...).后续又根据23年考研的大纲对内容做了一些调整,将二叉排序树和平衡二叉树的内容挪到 ...

  9. sdut 3341数据结构实验之二叉树二:遍历二叉树

    数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000MS Memory Limit: 65536K Problem Description 已知二叉树的一个按先序遍历输入的字符序列,如 ...

最新文章

  1. pfSense book之2.4安装指南
  2. 利用ComponentWillReceiveProps解决异步问题
  3. 哈夫曼编码之大根堆小根堆揭西县
  4. java 第三方代码_Java:如何使用第三方库?
  5. 考研院校选择【2022 考研 定专业就要这三步——专业必知、专业初选与精选】
  6. HeartBeat 集群组件概述
  7. 工作53:$router问题
  8. wince编译时找不到atls.lib
  9. 共享文件原理_fishhook 的实现原理浅析
  10. 用mac的safari浏览器调试ios手机的网页
  11. Python3与OpenCV3.3 图像处理(九)--高斯模糊
  12. 记录java对象修改过的字段_Java垃圾回收器与内存回收策略
  13. 复习JS事件及DOM
  14. PMBOK(第六版) PMP笔记——《八》第八章(项目质量管理)
  15. 知乎提示浏览器版本过低怎么办
  16. Anaconda 安装python时出错:Collecting package metadata (current_repodata.json): failed
  17. 计算个人所得税 (10 分)2019年个税新版规定:应纳税所得额为税前工资扣除五险一金,五险一金按工资22%比例计算。 个税起征点为5000元;
  18. FFmpeg的Android平台移植—编译篇
  19. 如何在Word中排出漂亮的代码,去除回车符,去除拼写检查
  20. 12. 整数转罗马数字

热门文章

  1. 用java画一个小猪佩奇_python 画个小猪佩奇
  2. php 除法,php中如何除法取整
  3. java怎么绘制魔方外观,AI简单绘制立体魔方教程
  4. 企业数字化转型思考系列文章(一)何为数字化转型?
  5. 笨办法学python2.0 习题1-10
  6. 关于Spark Steaming中的Processing Time/Total Delay/Processing Delay
  7. 乌镇饭局后,阿里腾讯走向了分岔路
  8. Keras学习之:tensorboard 异常报错及处理方法
  9. 【毕业设计】基于单片机的红外测距系统设计与实现 - c51 物联网 stm32
  10. 国内好用的免费DNS服务器