1.前言
二叉树是树的一种,有且仅有一个根节点。
二叉树的特殊形态如下
2.二叉树相关功能代码
下面的代码用到二叉树都是这个结构
2.1 二叉树的递归遍历
先序遍历:先访问根节点,然后左节点,右节点。上图访问顺序应该为(ABCDEFGH)
中序遍历:先访问左节点,然后根节点,右节点。上图访问顺序应该为(BDCEAFHG)
后序遍历:先访问左节点,然后右节点,根节点。上图访问顺序应该为(DECBHGFA)
#include<iostream>
//二叉树节点
typedef struct BINARYNODE
{
char ch;
BINARYNODE* lchild;
BINARYNODE* rchild;
}BinaryNode;
//递归先序遍历
void Recurison1(BinaryNode* root)
{
if (root == NULL)return;
//访问根节点
std::cout << root->ch;
//再访问左节点
Recurison1(root->lchild);
//再访问右节点
Recurison1(root->rchild);
}
//递归中序遍历
void Recurison2(BinaryNode* root)
{
if (root == NULL)return;
//再访问左节点
Recurison2(root->lchild);
//访问根节点
std::cout << root->ch;
//再访问右节点
Recurison2(root->rchild);
}
//递归后序遍历
void Recurison3(BinaryNode* root)
{
if (root == NULL)return;
//先访问左节点
Recurison3(root->lchild);
//再访问右节点
Recurison3(root->rchild);
//再访问根节点
std::cout << root->ch;
}
void CreateBinaryTress()
{
//创建节点
BinaryNode nodeA = { 'A',NULL,NULL};
BinaryNode nodeB = { 'B',NULL,NULL };
BinaryNode nodeC = { 'C',NULL,NULL };
BinaryNode nodeD = { 'D',NULL,NULL };
BinaryNode nodeE = { 'E',NULL,NULL };
BinaryNode nodeF = { 'F',NULL,NULL };
BinaryNode nodeG = { 'G',NULL,NULL };
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;
std::cout << "先序遍历为:";
//递归先序遍历
Recurison1(&nodeA);
std::cout <<"\n"<< "中序遍历为:";
//递归中序遍历
Recurison2(&nodeA);
std::cout << "\n" << "后序遍历为:";
//递归后序遍历
Recurison3(&nodeA);
}
int main()
{
CreateBinaryTress();
return 0;
}
运行结果:
2.2 二叉树的叶子节点数
叶子节点可以理解为下面不再有叶子,从上面的二叉树图可以看到就有三个叶子节点D E H
代码如下
#include<iostream>
//二叉树节点
typedef struct BINARYNODE
{
char ch;
BINARYNODE* lchild;
BINARYNODE* rchild;
}BinaryNode;
void CalculateLeafNum(BinaryNode* root,int* LeafNum)
{
if (root == NULL) return;
if (root->lchild == NULL && root->rchild==NULL) {
(*LeafNum)++;
}
//左子树的叶子结点数
CalculateLeafNum(root->lchild, LeafNum);
//右子树叶子结点数
CalculateLeafNum(root->rchild, LeafNum);
}
void CreateBinaryTress()
{
//创建节点
BinaryNode nodeA = { 'A',NULL,NULL};
BinaryNode nodeB = { 'B',NULL,NULL };
BinaryNode nodeC = { 'C',NULL,NULL };
BinaryNode nodeD = { 'D',NULL,NULL };
BinaryNode nodeE = { 'E',NULL,NULL };
BinaryNode nodeF = { 'F',NULL,NULL };
BinaryNode nodeG = { 'G',NULL,NULL };
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 LeafNum = 0;
CalculateLeafNum(&nodeA,&LeafNum);
std::cout << "叶子节点数为: " << LeafNum<<std::endl;
}
int main()
{
CreateBinaryTress();
return 0;
}
运行结果:
2.3 求二叉树的高度
#include<iostream>
//二叉树节点
typedef struct BINARYNODE
{
char ch;
BINARYNODE* lchild;
BINARYNODE* rchild;
}BinaryNode;
int TreeHeight(BinaryNode* root)
{
if (root == NULL) return 0;
int depth = 0;
int left_height = TreeHeight(root->lchild);
int right_height = TreeHeight(root->rchild);
depth = left_height > right_height ? left_height + 1 : right_height + 1;
return depth;
}
void CreateBinaryTress()
{
//创建节点
BinaryNode nodeA = { 'A',NULL,NULL };
BinaryNode nodeB = { 'B',NULL,NULL };
BinaryNode nodeC = { 'C',NULL,NULL };
BinaryNode nodeD = { 'D',NULL,NULL };
BinaryNode nodeE = { 'E',NULL,NULL };
BinaryNode nodeF = { 'F',NULL,NULL };
BinaryNode nodeG = { 'G',NULL,NULL };
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;
std::cout << "二叉树的高度为: " << TreeHeight(&nodeA) << std::endl;
}
int main()
{
CreateBinaryTress();
return 0;
}
运行结果:
2.4 二叉树的拷贝和释放
#include<iostream>
//二叉树节点
typedef struct BINARYNODE
{
char ch;
BINARYNODE* lchild;
BINARYNODE* rchild;
}BinaryNode;
//递归先序遍历
void Recurison1(BinaryNode* root)
{
if (root == NULL)return;
//访问根节点
std::cout << root->ch;
//再访问左节点
Recurison1(root->lchild);
//再访问右节点
Recurison1(root->rchild);
}
BinaryNode* CopyBinaryTree(BinaryNode* root)
{
if (root == NULL)return NULL;
BinaryNode* lchild=CopyBinaryTree(root->lchild);
BinaryNode* rchild = CopyBinaryTree(root->rchild);
BinaryNode* newnode = new BinaryNode;
newnode->ch = root->ch;
newnode->lchild = lchild;
newnode->rchild = rchild;
return newnode;
}
void FreeSpaceBinaryTree(BinaryNode* root)
{
if (root == NULL)return;
FreeSpaceBinaryTree(root->lchild);
FreeSpaceBinaryTree(root->rchild);
delete root;
}
void CreateBinaryTress()
{
//创建节点
BinaryNode nodeA = { 'A',NULL,NULL };
BinaryNode nodeB = { 'B',NULL,NULL };
BinaryNode nodeC = { 'C',NULL,NULL };
BinaryNode nodeD = { 'D',NULL,NULL };
BinaryNode nodeE = { 'E',NULL,NULL };
BinaryNode nodeF = { 'F',NULL,NULL };
BinaryNode nodeG = { 'G',NULL,NULL };
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;
BinaryNode* newn = CopyBinaryTree(&nodeA);
Recurison1(newn);
FreeSpaceBinaryTree(newn);
}
int main()
{
CreateBinaryTress();
return 0;
}
运行结果:
3. 总结
c++数据结构篇到此结束,后续可能会接着更新十大排序算法,大家共勉!