数据结构笔记(6)二叉树的实现
目录
二叉树定义
二叉树图解
特殊的二叉树
二叉树的性质
二叉树的基本代码实现
二叉数的定义
二叉树的输入(创建)
二叉树的遍历
二叉树的深度优先遍历
二叉树的广度优先遍历
二叉树的基本功能函数的实现
返回宽度和深度
深度
宽度
返回节点个数
返回二度节点
返回一度节点
返回叶子节点(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)二叉树的实现相关推荐
- 数据结构笔记:二叉树的构造(根据遍历顺序构造二叉树)
目录 给出先序遍历序列和中序遍历序列可以唯一确定二叉树 给出后序遍历序列和中序遍历序列可以唯一确定二叉树 题: 给出先序遍历序列和中序遍历序列可以唯一确定二叉树 给出后序遍历序列和中序遍历序列可以唯一 ...
- 数据结构笔记6: 二叉树和其他树
树的一般定义 树 线性表.表:不适合描述层次结构数据 树(tree):是一个非空的有限元素的集合,其中有一个特殊的元素称为根,余下的元素组成树的若干子树 递归的思想:每棵树=根+若干棵子树,每棵子树= ...
- 数据结构笔记(王道考研) 第五章:树和二叉树
大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,该课属于付费课程(不过盗版网盘资源也不难找...).后续又根据23年考研的大纲对内容做了一些调整,将二叉排序树和平衡二叉树的内容挪到 ...
- 数据结构笔记(王道考研) 第八章:排序
大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,该课属于付费课程(不过盗版网盘资源也不难找...).后续又根据23年考研的大纲对内容做了一些调整,将二叉排序树和平衡二叉树的内容挪到 ...
- 一、考研数据结构笔记——引言及目录
一.关于我理解的数据结构 1. 引言 本人自2021年3月准备考研,考研主要是为了提升学历,本科院校不是理想.迫切需要提高学历. 写这刊博客,主要是总结我考研路上对数据结构的一些理解,以及为了方便我后 ...
- 鸿钧老祖 数据结构笔记01:编程面试过程中常见的10大算法(java)
以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java的角度看问题,包含下面的这些概念: ...
- 数据结构笔记(王道考研) 第一章:绪论
大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,该课属于付费课程(不过盗版网盘资源也不难找...).后续又根据23年考研的大纲对内容做了一些调整,将二叉排序树和平衡二叉树的内容挪到 ...
- 数据结构笔记(王道考研) 第七章:查找
大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,该课属于付费课程(不过盗版网盘资源也不难找...).后续又根据23年考研的大纲对内容做了一些调整,将二叉排序树和平衡二叉树的内容挪到 ...
- sdut 3341数据结构实验之二叉树二:遍历二叉树
数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000MS Memory Limit: 65536K Problem Description 已知二叉树的一个按先序遍历输入的字符序列,如 ...
最新文章
- pfSense book之2.4安装指南
- 利用ComponentWillReceiveProps解决异步问题
- 哈夫曼编码之大根堆小根堆揭西县
- java 第三方代码_Java:如何使用第三方库?
- 考研院校选择【2022 考研 定专业就要这三步——专业必知、专业初选与精选】
- HeartBeat 集群组件概述
- 工作53:$router问题
- wince编译时找不到atls.lib
- 共享文件原理_fishhook 的实现原理浅析
- 用mac的safari浏览器调试ios手机的网页
- Python3与OpenCV3.3 图像处理(九)--高斯模糊
- 记录java对象修改过的字段_Java垃圾回收器与内存回收策略
- 复习JS事件及DOM
- PMBOK(第六版) PMP笔记——《八》第八章(项目质量管理)
- 知乎提示浏览器版本过低怎么办
- Anaconda 安装python时出错:Collecting package metadata (current_repodata.json): failed
- 计算个人所得税 (10 分)2019年个税新版规定:应纳税所得额为税前工资扣除五险一金,五险一金按工资22%比例计算。 个税起征点为5000元;
- FFmpeg的Android平台移植—编译篇
- 如何在Word中排出漂亮的代码,去除回车符,去除拼写检查
- 12. 整数转罗马数字
热门文章
- 用java画一个小猪佩奇_python 画个小猪佩奇
- php 除法,php中如何除法取整
- java怎么绘制魔方外观,AI简单绘制立体魔方教程
- 企业数字化转型思考系列文章(一)何为数字化转型?
- 笨办法学python2.0 习题1-10
- 关于Spark Steaming中的Processing Time/Total Delay/Processing Delay
- 乌镇饭局后,阿里腾讯走向了分岔路
- Keras学习之:tensorboard 异常报错及处理方法
- 【毕业设计】基于单片机的红外测距系统设计与实现 - c51 物联网 stm32
- 国内好用的免费DNS服务器