二叉树的相关代码实现

贴出自己练习的二叉树相关代码的实现,如有不对,烦请指出。
为了方便读阅,前面将分离贴出每个功能的实现。完整的头文件、源文件和main函数代码将在文末整合贴出。

1.二叉树的一些概念

  1. 节点的度:一个节点含有的子节点的个数。
  2. 树的度:树中,最大节点的度被称之为树的度。
  3. 树的深度:树中节点的最大层次。
  4. 叶子节点:度为0的节点。
  5. 二叉树:树中节点的度不大于2的有序树,有左右子树之分,子树次序不能颠倒。
  6. 满二叉树:树中除叶子节点外,其他所有节点的度都为2,并且叶子节点都在同一层上。
  7. 完全二叉树:对于深度为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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值