二叉树的相关代码实现
贴出自己练习的二叉树相关代码的实现,如有不对,烦请指出。
为了方便读阅,前面将分离贴出每个功能的实现。完整的头文件、源文件和main函数代码将在文末整合贴出。
1.二叉树的一些概念
- 节点的度:一个节点含有的子节点的个数。
- 树的度:树中,最大节点的度被称之为树的度。
- 树的深度:树中节点的最大层次。
- 叶子节点:度为0的节点。
- 二叉树:树中节点的度不大于2的有序树,有左右子树之分,子树次序不能颠倒。
- 满二叉树:树中除叶子节点外,其他所有节点的度都为2,并且叶子节点都在同一层上。
- 完全二叉树:对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树(我理解为:若设二叉树的深度为k,除第 k 层外,其它各层 (1~k-1) 的结点数都达到最大个数,第k 层所有的结点都连续集中在最左边,这就是完全二叉树。)。注意:完全二叉树的叶子节点只会出现在最下层和次下层,而且最下层的叶子节点集中在树的左边。
2. 二叉树的创建:
//创建二叉树
TBinTree *CBinTree::PreCreateBinTree(vector<char> TreeValue, int *NodeNo)
{
//遇到 # 则为空节点,直接返回NULL
if (TreeValue.at(*NodeNo) == '#')
{
(*NodeNo)++;
return NULL;
}
//构建根节点
TBinTree *pNewNode = new TBinTree();
pNewNode->dwValue = TreeValue.at(*NodeNo);
pNewNode->LTree = NULL;
pNewNode->RTree = NULL;
(*NodeNo)++;//构建下一个参数
pNewNode->LTree = PreCreateBinTree(TreeValue, NodeNo);
pNewNode->RTree = PreCreateBinTree(TreeValue, NodeNo);
return pNewNode;
}
3. 先序遍历二叉树(根 左 右):
//先序遍历
void CBinTree::PreTraTree(TBinTree *pTreeRoot)
{
if (pTreeRoot == NULL)return;
cout << pTreeRoot->dwValue;
PreTraTree(pTreeRoot->LTree);
PreTraTree(pTreeRoot->RTree);
}
4. 中序遍历二叉树(左 根 右):
//中序遍历
void CBinTree::MidTraTree(TBinTree *pTreeRoot)
{
if (pTreeRoot == NULL)return;
MidTraTree(pTreeRoot->LTree);
cout << pTreeRoot->dwValue;
MidTraTree(pTreeRoot->RTree);
}
5. 后序遍历二叉树(左 右 根):
//后序遍历
void CBinTree::PostTraTree(TBinTree *pTreeRoot)
{
if (pTreeRoot == NULL)return;
PostTraTree(pTreeRoot->LTree);
PostTraTree(pTreeRoot->RTree);
cout << pTreeRoot->dwValue;
}
6. 求树的最大深度:
//树的最大深度
int CBinTree::MaxTreeDepth(TBinTree *pTreeRoot)
{
int dwMaxDepth = 0, dwLeftDepth = 0, dwRightDepth = 0;
if (pTreeRoot == NULL)//节点不存在,度不增加
{
return 0;
}
if ( pTreeRoot->LTree == NULL &&pTreeRoot->RTree == NULL )//节点存在,但无孩子节点,则为叶子节点,度+1
{
return 1;
}
//递归:得到每个左右独立子树的深度,并比较得出最大的度
dwLeftDepth = MaxTreeDepth(pTreeRoot->LTree);
dwRightDepth = MaxTreeDepth(pTreeRoot->RTree);
dwMaxDepth = dwLeftDepth > dwRightDepth ? dwLeftDepth : dwRightDepth;
return (dwMaxDepth+1);//因为递归得到得是子树的度,因此要加上此节点的度,才算是pTreeRoot节点最大的度
}
7. 求叶子节点的数量:
//树的叶子节点个数
int CBinTree::LeafNodeNum(TBinTree *pTreeRoot)
{
int dwLeafNum = 0;
if (pTreeRoot == NULL)//节点不存在
{
return 0;
}
if (pTreeRoot->LTree == NULL &&pTreeRoot->RTree == NULL)//节点存在,但无孩子节点,则为叶子节点,数量+1
{
return 1;
}
dwLeafNum += LeafNodeNum(pTreeRoot->LTree);
dwLeafNum += LeafNodeNum(pTreeRoot->RTree);
return dwLeafNum;
完整代码:
头文件:
#pragma once
#include "stdafx.h"
typedef struct tagBinTree
{
char dwValue;//二叉树的值
tagBinTree *LTree;//左子树
tagBinTree *RTree;//右子树
}TBinTree;
class CBinTree
{
public:
CBinTree() :pRoot(NULL){};
~CBinTree();
private:
TBinTree *pRoot;//二叉树根节点
public:
void DeleteBinTree(TBinTree *pTBinTree);//删除二叉树
TBinTree *GetTreeRoot();//返回先序创建的二叉树的根节点
//创建二叉树总接口,函数体会分表实现 先序,中序,后序创建二叉树
TBinTree *CreateBinTree(vector<char> TreeValue);
//创建二叉树(递归) 参数:TreeValue-用户输入的各节点值,#代表空节点 NodeNo-TreeValue容器的下标,表达当前构造到第几个值
TBinTree *PreCreateBinTree(vector<char> TreeValue,int *NodeNo);
//先序、中序、后序遍历二叉树
void PreTraTree(TBinTree *pTreeRoot);
void MidTraTree(TBinTree *pTreeRoot);
void PostTraTree(TBinTree *pTreeRoot);
//树的最大深度
int MaxTreeDepth(TBinTree *pTreeRoot);
//树的叶子节点个数
int LeafNodeNum(TBinTree *pTreeRoot);
};
源文件:
#include "stdafx.h"
#include "BinTree.h"
CBinTree::~CBinTree()
{
if (pRoot != NULL)
{
//删除二叉树
DeleteBinTree(pRoot);
}
}
//删除二叉树
void CBinTree::DeleteBinTree(TBinTree *pTBinTree)
{
if (pTBinTree != NULL)
{
if (pTBinTree->LTree != NULL)
{
DeleteBinTree(pTBinTree->LTree);
}
if (pTBinTree->RTree != NULL)
{
DeleteBinTree(pTBinTree->RTree);
}
delete pTBinTree;
pTBinTree = NULL;
}
return;
}
//得到二叉树的根节点
TBinTree *CBinTree::GetTreeRoot()
{
return pRoot;
}
//创建二叉树接口,函数体会分表实现 先序,中序,后序创建二叉树
TBinTree *CBinTree::CreateBinTree(vector<char> TreeValue)
{
int dwPreNo = 0;
pRoot = PreCreateBinTree(TreeValue,&dwPreNo);
return pRoot;
}
//先序创建二叉树
TBinTree *CBinTree::PreCreateBinTree(vector<char> TreeValue, int *NodeNo)
{
if (TreeValue.at(*NodeNo) == '#')
{
(*NodeNo)++;
return NULL;
}
//构建根节点
TBinTree *pNewNode = new TBinTree();
pNewNode->dwValue = TreeValue.at(*NodeNo);
pNewNode->LTree = NULL;
pNewNode->RTree = NULL;
(*NodeNo)++;//构建下一个参数
pNewNode->LTree = PreCreateBinTree(TreeValue, NodeNo);
pNewNode->RTree = PreCreateBinTree(TreeValue, NodeNo);
return pNewNode;
}
//先序遍历
void CBinTree::PreTraTree(TBinTree *pTreeRoot)
{
if (pTreeRoot == NULL)return;
cout << pTreeRoot->dwValue;
PreTraTree(pTreeRoot->LTree);
PreTraTree(pTreeRoot->RTree);
}
//中序遍历
void CBinTree::MidTraTree(TBinTree *pTreeRoot)
{
if (pTreeRoot == NULL)return;
MidTraTree(pTreeRoot->LTree);
cout << pTreeRoot->dwValue;
MidTraTree(pTreeRoot->RTree);
}
//后序遍历
void CBinTree::PostTraTree(TBinTree *pTreeRoot)
{
if (pTreeRoot == NULL)return;
PostTraTree(pTreeRoot->LTree);
PostTraTree(pTreeRoot->RTree);
cout << pTreeRoot->dwValue;
}
//树的最大深度
int CBinTree::MaxTreeDepth(TBinTree *pTreeRoot)
{
int dwMaxDepth = 0, dwLeftDepth = 0, dwRightDepth = 0;
if (pTreeRoot == NULL)//节点不存在,度不增加
{
return 0;
}
if ( pTreeRoot->LTree == NULL &&pTreeRoot->RTree == NULL )//节点存在,但无孩子节点,则为叶子节点,度+1
{
return 1;
}
//递归:得到每个左右独立子树的深度,并比较得出最大的度
dwLeftDepth = MaxTreeDepth(pTreeRoot->LTree);
dwRightDepth = MaxTreeDepth(pTreeRoot->RTree);
dwMaxDepth = dwLeftDepth > dwRightDepth ? dwLeftDepth : dwRightDepth;
return (dwMaxDepth+1);//因为递归得到得是子树的度,因此要加上此节点的度,才算是pTreeRoot节点最大的度
}
//树的叶子节点个数
int CBinTree::LeafNodeNum(TBinTree *pTreeRoot)
{
int dwLeafNum = 0;
if (pTreeRoot == NULL)//节点不存在
{
return 0;
}
if (pTreeRoot->LTree == NULL &&pTreeRoot->RTree == NULL)//节点存在,但无孩子节点,则为叶子节点,数量+1
{
return 1;
}
dwLeafNum += LeafNodeNum(pTreeRoot->LTree);
dwLeafNum += LeafNodeNum(pTreeRoot->RTree);
return dwLeafNum;
}
main函数:
#include "stdafx.h"
#include "BinTree.h"
int main()
{
CBinTree *pTbinTree = new CBinTree();
TBinTree *pRoot = NULL;
vector<char> TreeValue;
char chNodeValue = 0;
cout << "请输入需要创建的二叉树的值,数字表示节点值,#表示空节点" << endl;
while ( chNodeValue = getchar() )
{
if (chNodeValue == '\n') break;
TreeValue.push_back(chNodeValue);
}
//得到先序创建的二叉树的根节点
pRoot = pTbinTree->CreateBinTree(TreeValue);
cout << "先序遍历结果为:";
pTbinTree->PreTraTree(pRoot);
cout << endl;
cout << "中序遍历结果为:";
pTbinTree->MidTraTree(pRoot);
cout << endl;
cout << "后序遍历结果为:";
pTbinTree->PostTraTree(pRoot);
cout << endl;
cout << "输的深度为:"<< pTbinTree->MaxTreeDepth(pRoot) << endl;
cout << "叶子节点数量为:" << pTbinTree->LeafNodeNum(pRoot) << endl;
delete pTbinTree;
system("pause");
return 0;
}