由一个或多个(n≥0)结点组成的有限集合T ,
有且仅有一个结点称为根( root ) ,
当n>1时,
其余的结点分为m(m≥0)个互不相交的有限集合T1,T2,…,Tm。
每个集合本身又是棵树,被称作这个根的子树。
( 1:n )
根
→即根结点(没有前驱)叶子
→即终端结点(没有后继)双亲
→即上层的那个结点(直接前驱) parent孩子
→即下层结点的子树(直接后继)child-上图中的结点数 = 13 ,树的度 = 3 ,数的深度 = 4
事物之问的逻辑关系可以通过数的形式很直观的表示出来,如下图:
用广义表表示法表示上图:
中国(河北(保定,石家庄),广东(广州,东莞),山东(青岛,济南))
根作为由子树森林组成的表的名宁写在表的左边。
左孩子右兄弟表示法可以将一颗多叉树转化为一颖二叉树:
n ( n≥0 )个结点的有限集合,由一个根结点以及两棵互不相交的、分别称为左子树和
右子树的二叉树组成。
一对二(1:2)
每个结点最多只有两棵子树(丕存在度大于2的结点);
左子树和右子树次序不能颠倒(有序树)
特点:每层都有”充满”了结点
除最后一层外,每一层上的节点均达到最大值;在最后一层上只缺少右边的若干结点
理解:k-1层与满二叉树完全相同,第k层结点尽量靠左
指按某条搜索路线遍访每个结点且不重复(又称周游入
它是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的基础和核
心。
牢记一种约定,对每个结点的查看都是“先左后右”。
限定先左后右,树的遍历有三种实现方案∶
注:"先、中、后”的意思是指访问的结点D是先于子树出现还是后于子树出现。
从递归的角度看,这三种算法是完全相同的,
或者说这三种遍历算法的访问路径是相同的,
只是访问结点的时机不同。
从虚线的出发点到终点的路径上,每个结点经过3次。
先序遍历:根 左 右
中序遍历:左 根 右
后续遍历:左 右 根
#include <stdio.h>
#include "string.h"
#include "stdlib.h"
struct BinaryNode{
char ch;//数据域
struct BinaryNode * LChild;//左孩子节点
struct BinaryNode * RChild;//右孩子节点
};
//递归遍历的函数
void recursion(struct BinaryNode * root){
if(root == NULL){
return;
}
//先序遍历,先根 再左 再右
printf ("%c ",root->ch);
recursion (root->LChild);
recursion (root->RChild);
}
void test01(){
struct BinaryNode nodeA = {'A',NULL,NULL};
struct BinaryNode nodeB = {'B',NULL,NULL};
struct BinaryNode nodeC = {'C',NULL,NULL};
struct BinaryNode nodeD = {'D',NULL,NULL};
struct BinaryNode nodeE = {'E',NULL,NULL};
struct BinaryNode nodeF = {'F',NULL,NULL};
struct BinaryNode nodeG = {'G',NULL,NULL};
struct BinaryNode nodeH = {'H',NULL,NULL};
//建立结点之间的关系
nodeA.LChild = &nodeB;
nodeA.RChild = &nodeF;
nodeB.RChild = &nodeC;
nodeC.LChild = &nodeD;
nodeC.RChild = &nodeE;
nodeF.RChild = &nodeG;
nodeG.LChild = &nodeH;
//递归遍历
recursion(&nodeA);
}
int main () {
test01();
return 0;
}
运行结果
#include <stdio.h>
#include "string.h"
#include "stdlib.h"
struct BinaryNode{
char ch;//数据域
struct BinaryNode * LChild;//左孩子节点
struct BinaryNode * RChild;//右孩子节点
};
//递归遍历的函数
void preorderRecursion(struct BinaryNode * root){
if(root == NULL){
return;
}
//先序遍历,先根 再左 再右
printf ("%c ",root->ch);
preorderRecursion (root->LChild);
preorderRecursion (root->RChild);
}
//递归遍历的函数
void inRecursion(struct BinaryNode * root){
if(root == NULL){
return;
}
//中序遍历,先根 再左 再右
inRecursion (root->LChild);
printf ("%c ",root->ch);
inRecursion (root->RChild);
}
//递归遍历的函数
void afterRecursion(struct BinaryNode * root){
if(root == NULL){
return;
}
//中序遍历,先根 再左 再右
afterRecursion (root->LChild);
afterRecursion (root->RChild);
printf ("%c ",root->ch);
}
void test01(){
struct BinaryNode nodeA = {'A',NULL,NULL};
struct BinaryNode nodeB = {'B',NULL,NULL};
struct BinaryNode nodeC = {'C',NULL,NULL};
struct BinaryNode nodeD = {'D',NULL,NULL};
struct BinaryNode nodeE = {'E',NULL,NULL};
struct BinaryNode nodeF = {'F',NULL,NULL};
struct BinaryNode nodeG = {'G',NULL,NULL};
struct BinaryNode nodeH = {'H',NULL,NULL};
//建立结点之间的关系
nodeA.LChild = &nodeB;
nodeA.RChild = &nodeF;
nodeB.RChild = &nodeC;
nodeC.LChild = &nodeD;
nodeC.RChild = &nodeE;
nodeF.RChild = &nodeG;
nodeG.LChild = &nodeH;
//递归遍历
printf("先序遍历\n");
preorderRecursion(&nodeA);
printf("\n中序遍历\n");
inRecursion(&nodeA);
printf("\n后序遍历\n");
afterRecursion(&nodeA);
}
int main () {
test01();
return 0;
}
运行结果
#include <stdio.h>
#include "string.h"
#include "stdlib.h"
struct BinaryNode{
char ch;//数据域
struct BinaryNode * LChild;//左孩子节点
struct BinaryNode * RChild;//右孩子节点
};
//统计叶子数量的函数
void calculateLeafNum(struct BinaryNode * root, int * num){
//递归的结束条件
if(root == NULL){
return;
}
//判断当前节点的左孩子和右孩子是否为空。如果为空数字就累加
if(root->LChild == NULL && root->RChild == NULL){
(*num)++;
}
calculateLeafNum (root->LChild,num);
calculateLeafNum (root->RChild,num);
}
void test01(){
struct BinaryNode nodeA = {'A',NULL,NULL};
struct BinaryNode nodeB = {'B',NULL,NULL};
struct BinaryNode nodeC = {'C',NULL,NULL};
struct BinaryNode nodeD = {'D',NULL,NULL};
struct BinaryNode nodeE = {'E',NULL,NULL};
struct BinaryNode nodeF = {'F',NULL,NULL};
struct BinaryNode nodeG = {'G',NULL,NULL};
struct BinaryNode nodeH = {'H',NULL,NULL};
//建立结点之间的关系
nodeA.LChild = &nodeB;
nodeA.RChild = &nodeF;
nodeB.RChild = &nodeC;
nodeC.LChild = &nodeD;
nodeC.RChild = &nodeE;
nodeF.RChild = &nodeG;
nodeG.LChild = &nodeH;
//求树中的叶子的数量
int num = 0;
calculateLeafNum(&nodeA ,&num);
printf ("LeafNum=%d",num);
}
int main () {
test01();
return 0;
}
int getTreeHeight(struct BinaryNode* root){
if(root == NULL){
return 0;
}
//求出左子树的高度
int LHeight = getTreeHeight(root->LChild);
//计算右子树的高度
int RHeight = getTreeHeight(root->RChild);
//取左子树和右子树,中最大的值 +1
int height = LHeight > RHeight ? LHeight + 1 : RHeight + 1;
return height;
}
计算相关的所有代码
#include <stdio.h>
struct BinaryNode{
char ch;//数据域
struct BinaryNode * LChild;//左孩子节点
struct BinaryNode * RChild;//右孩子节点
};
//统计叶子数量的函数
void calculateLeafNum(struct BinaryNode * root, int * num){
//递归的结束条件
if(root == NULL){
return;
}
//判断当前节点的左孩子和右孩子是否为空。如果为空数字就累加
if(root->LChild == NULL && root->RChild == NULL){
(*num)++;
}
calculateLeafNum (root->LChild,num);
calculateLeafNum (root->RChild,num);
}
int getTreeHeight(struct BinaryNode* root){
if(root == NULL){
return 0;
}
//求出左子树的高度
int LHeight = getTreeHeight(root->LChild);
//计算右子树的高度
int RHeight = getTreeHeight(root->RChild);
//取左子树和右子树,中最大的值 +1
int height = LHeight > RHeight ? LHeight + 1 : RHeight + 1;
return height;
}
void test01(){
struct BinaryNode nodeA = {'A',NULL,NULL};
struct BinaryNode nodeB = {'B',NULL,NULL};
struct BinaryNode nodeC = {'C',NULL,NULL};
struct BinaryNode nodeD = {'D',NULL,NULL};
struct BinaryNode nodeE = {'E',NULL,NULL};
struct BinaryNode nodeF = {'F',NULL,NULL};
struct BinaryNode nodeG = {'G',NULL,NULL};
struct BinaryNode nodeH = {'H',NULL,NULL};
//建立结点之间的关系
nodeA.LChild = &nodeB;
nodeA.RChild = &nodeF;
nodeB.RChild = &nodeC;
nodeC.LChild = &nodeD;
nodeC.RChild = &nodeE;
nodeF.RChild = &nodeG;
nodeG.LChild = &nodeH;
//1、求树中的叶子的数量
int num = 0;
calculateLeafNum(&nodeA ,&num);
printf ("LeafNum=%d\n",num);
//2、求树的高度、深度
int height = getTreeHeight(&nodeA);
printf ("tree height is=%d\n",height);
}
int main () {
test01();
return 0;
}
struct BinaryNode * copyBinaryTree(struct BinaryNode* root){
if(root == NULL){
return NULL;
}
//先拷贝 左子树
struct BinaryNode * LChild = copyBinaryTree (root->LChild);
//再拷贝 右子树
struct BinaryNode * RChild = copyBinaryTree (root->RChild);
//创建新的节点
struct BinaryNode * newNode = malloc(sizeof (struct BinaryNode ));
newNode->LChild = LChild;
newNode->RChild = RChild;
//返回给新用户
newNode->ch = root->ch;
return newNode;
}
//遍历树
void showBinaryTree(struct BinaryNode * root){
if(root == NULL){
return;
}
printf ("%c",root->ch);
showBinaryTree (root->LChild);
showBinaryTree (root->RChild);
}
全部测试代码
#include <stdio.h>
#include "string.h"
#include "stdlib.h"
struct BinaryNode{
char ch;//数据域
struct BinaryNode * LChild;//左孩子节点
struct BinaryNode * RChild;//右孩子节点
};
//统计叶子数量的函数
void calculateLeafNum(struct BinaryNode * root, int * num){
//递归的结束条件
if(root == NULL){
return;
}
//判断当前节点的左孩子和右孩子是否为空。如果为空数字就累加
if(root->LChild == NULL && root->RChild == NULL){
(*num)++;
}
calculateLeafNum (root->LChild,num);
calculateLeafNum (root->RChild,num);
}
int getTreeHeight(struct BinaryNode* root){
if(root == NULL){
return 0;
}
//求出左子树的高度
int LHeight = getTreeHeight(root->LChild);
//计算右子树的高度
int RHeight = getTreeHeight(root->RChild);
//取左子树和右子树,中最大的值 +1
int height = LHeight > RHeight ? LHeight + 1 : RHeight + 1;
return height;
}
struct BinaryNode * copyBinaryTree(struct BinaryNode* root){
if(root == NULL){
return NULL;
}
//先拷贝 左子树
struct BinaryNode * LChild = copyBinaryTree (root->LChild);
//再拷贝 右子树
struct BinaryNode * RChild = copyBinaryTree (root->RChild);
//创建新的节点
struct BinaryNode * newNode = malloc(sizeof (struct BinaryNode ));
newNode->LChild = LChild;
newNode->RChild = RChild;
//返回给新用户
newNode->ch = root->ch;
return newNode;
}
//遍历树
void showBinaryTree(struct BinaryNode * root){
if(root == NULL){
return;
}
printf ("%c",root->ch);
showBinaryTree (root->LChild);
showBinaryTree (root->RChild);
}
void test01(){
struct BinaryNode nodeA = {'A',NULL,NULL};
struct BinaryNode nodeB = {'B',NULL,NULL};
struct BinaryNode nodeC = {'C',NULL,NULL};
struct BinaryNode nodeD = {'D',NULL,NULL};
struct BinaryNode nodeE = {'E',NULL,NULL};
struct BinaryNode nodeF = {'F',NULL,NULL};
struct BinaryNode nodeG = {'G',NULL,NULL};
struct BinaryNode nodeH = {'H',NULL,NULL};
//建立结点之间的关系
nodeA.LChild = &nodeB;
nodeA.RChild = &nodeF;
nodeB.RChild = &nodeC;
nodeC.LChild = &nodeD;
nodeC.RChild = &nodeE;
nodeF.RChild = &nodeG;
nodeG.LChild = &nodeH;
printf ("show BinaryTree\n");
showBinaryTree(&nodeA);
//1、求树中的叶子的数量
int num = 0;
calculateLeafNum(&nodeA ,&num);
printf ("\nLeafNum=%d\n",num);
//2、求树的高度、深度
int height = getTreeHeight(&nodeA);
printf ("tree height is=%d\n",height);
//3、拷贝二叉树
struct BinaryNode * newTree = copyBinaryTree(&nodeA);
printf ("show Copy BinaryTree\n");
showBinaryTree(newTree);
}
int main () {
test01();
return 0;
}
运行结果
//释放二叉树freeTree
void freeTree(struct BinaryNode * root )
{
if(root == NULL){
return;
}
//先释放左子树
freeTree (root->LChild);
//再释放右子树
freeTree (root->RChild);
printf ("%c __is free\n",root->ch);
//释放根节点
free(root);
}
运行测试所有代码
#include <stdio.h>
#include "string.h"
#include "stdlib.h"
struct BinaryNode{
char ch;//数据域
struct BinaryNode * LChild;//左孩子节点
struct BinaryNode * RChild;//右孩子节点
};
//统计叶子数量的函数
void calculateLeafNum(struct BinaryNode * root, int * num){
//递归的结束条件
if(root == NULL){
return;
}
//判断当前节点的左孩子和右孩子是否为空。如果为空数字就累加
if(root->LChild == NULL && root->RChild == NULL){
(*num)++;
}
calculateLeafNum (root->LChild,num);
calculateLeafNum (root->RChild,num);
}
int getTreeHeight(struct BinaryNode* root){
if(root == NULL){
return 0;
}
//求出左子树的高度
int LHeight = getTreeHeight(root->LChild);
//计算右子树的高度
int RHeight = getTreeHeight(root->RChild);
//取左子树和右子树,中最大的值 +1
int height = LHeight > RHeight ? LHeight + 1 : RHeight + 1;
return height;
}
struct BinaryNode * copyBinaryTree(struct BinaryNode* root){
if(root == NULL){
return NULL;
}
//先拷贝 左子树
struct BinaryNode * LChild = copyBinaryTree (root->LChild);
//再拷贝 右子树
struct BinaryNode * RChild = copyBinaryTree (root->RChild);
//创建新的节点
struct BinaryNode * newNode = malloc(sizeof (struct BinaryNode ));
newNode->LChild = LChild;
newNode->RChild = RChild;
//返回给新用户
newNode->ch = root->ch;
return newNode;
}
//遍历树
void showBinaryTree(struct BinaryNode * root){
if(root == NULL){
return;
}
printf ("%c",root->ch);
showBinaryTree (root->LChild);
showBinaryTree (root->RChild);
}
//释放二叉树freeTree
void freeTree(struct BinaryNode * root )
{
if(root == NULL){
return;
}
//先释放左子树
freeTree (root->LChild);
//再释放右子树
freeTree (root->RChild);
printf ("%c __is free\n",root->ch);
//释放根节点
free(root);
}
void test01(){
struct BinaryNode nodeA = {'A',NULL,NULL};
struct BinaryNode nodeB = {'B',NULL,NULL};
struct BinaryNode nodeC = {'C',NULL,NULL};
struct BinaryNode nodeD = {'D',NULL,NULL};
struct BinaryNode nodeE = {'E',NULL,NULL};
struct BinaryNode nodeF = {'F',NULL,NULL};
struct BinaryNode nodeG = {'G',NULL,NULL};
struct BinaryNode nodeH = {'H',NULL,NULL};
//建立结点之间的关系
nodeA.LChild = &nodeB;
nodeA.RChild = &nodeF;
nodeB.RChild = &nodeC;
nodeC.LChild = &nodeD;
nodeC.RChild = &nodeE;
nodeF.RChild = &nodeG;
nodeG.LChild = &nodeH;
printf ("show BinaryTree\n");
showBinaryTree(&nodeA);
//1、求树中的叶子的数量
int num = 0;
calculateLeafNum(&nodeA ,&num);
printf ("\nLeafNum=%d\n",num);
//2、求树的高度、深度
int height = getTreeHeight(&nodeA);
printf ("tree height is=%d\n",height);
//3、拷贝二叉树
struct BinaryNode * newTree = copyBinaryTree(&nodeA);
printf ("show Copy BinaryTree\n");
showBinaryTree(newTree);
//4、释放二叉树
freeTree(newTree);
}
int main () {
test01();
return 0;
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq_44757034/article/details/120254584
内容来源于网络,如有侵权,请联系作者删除!