C++实现二叉树相关操作

测试环境:windows 7 vs2010

主要实现二叉树的初始化递归和非递归遍历,层次遍历,获取叶子节点的个数,获取树的高度以及镜像树,部分代码也参考了互联网上的相关资料。

源程序:

BinaryTreeNode.h

#ifndef _BINARY_NODE
#define _BINARY_NODE

#include<iostream>
using namespace std;
template<class ItemType>
struct BinaryTreeNode
{
	ItemType item;
	BinaryTreeNode<ItemType> *leftPtr;
	BinaryTreeNode<ItemType> *rightPtr;
	friend ostream &operator<<(ostream &out,BinaryTreeNode &btn)
	{
		out<<" "<<btn.item;
		return out;
	}
	friend istream &operator>>(istream &input,BinaryTreeNode &btn)
	{
		input>>btn.item;
		return input;
	}
};

#endif

BinaryTree.h

#ifndef _BINARY_TREE
#define _BINARY_TREE

#include"BinaryTreeNode.h"
template<class ItemType>
class BinaryTree
{
private:
	BinaryTreeNode<ItemType> *rootPtr;
	void creatBinaryTree(BinaryTreeNode<ItemType> **rootPtr);
public:
	BinaryTree(BinaryTreeNode<ItemType> *rootPtr=nullptr);
	~BinaryTree(void);
	void initBinaryTree();
	BinaryTreeNode<ItemType> *getTreeRoot() const;
	void mirrorUseRecursion(BinaryTreeNode<ItemType> *rootPtr);//镜像树
	void preOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const;//递归先序遍历
	void inOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const;//递归中序遍历
	void postOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const;//递归后序遍历
	void preOrderUseStack() const;//非递归先序遍历
	void inOrderUseStack() const;//非递归中序遍历
	void postOrderUseStack() const;//非递归后序遍历
	void LevelOrder()const;//层次遍历
	int getLeafNum(BinaryTreeNode<ItemType> *rootPtr) const;//获取树的叶子节点数
	int getHeight(BinaryTreeNode<ItemType> *rootPtr);//获取树高度
	void clear();//清空树
};

#endif

BinaryTree.cpp

#include "BinaryTree.h"
#define TREE_EOF -1
#include<stack>
#include<deque>
template<class ItemType>
BinaryTree<ItemType>::BinaryTree(BinaryTreeNode<ItemType> *rootPtr=nullptr)
{
	this->rootPtr=rootPtr;
}

template<class ItemType>
BinaryTree<ItemType>::~BinaryTree(void)
{
	this->clear();
}

template<class ItemType>
void BinaryTree<ItemType>::creatBinaryTree(BinaryTreeNode<ItemType> **rootPtr)
{
	ItemType data;
	cin>>data;
	if(data!=TREE_EOF)
	{
		*rootPtr=new BinaryTreeNode<ItemType>;
		(*rootPtr)->item=data;
		cout<<"请输入"<<data<<"左子树:"<<endl;
		creatBinaryTree(&(*rootPtr)->leftPtr);
		cout<<"请输入"<<data<<"右子树:"<<endl;
		creatBinaryTree(&(*rootPtr)->rightPtr);
	}
	else
	{
		*rootPtr=nullptr;
	}

}
template<class ItemType>
void  BinaryTree<ItemType>::initBinaryTree()
{
	cout<<"开始创建二叉树 \n"<<endl;
	creatBinaryTree(&this->rootPtr);
}
template<class ItemType>
void BinaryTree<ItemType>::inOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr)const
{
	if(rootPtr==nullptr)
	{
		return;
	}
	inOrderUseRecursion(rootPtr->leftPtr);
	cout<<*rootPtr;
	inOrderUseRecursion(rootPtr->rightPtr);
}
template<class ItemType>
void BinaryTree<ItemType>::preOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const
{
	if(rootPtr==nullptr)
	{
		return;
	}
	cout<<*rootPtr;
	preOrderUseRecursion(rootPtr->leftPtr);
	preOrderUseRecursion(rootPtr->rightPtr);
}

template<class ItemType>
void BinaryTree<ItemType>::postOrderUseRecursion(BinaryTreeNode<ItemType> *rootPtr) const
{
	if(rootPtr==nullptr)
	{
		return;
	}
	postOrderUseRecursion(rootPtr->leftPtr);
	postOrderUseRecursion(rootPtr->rightPtr);
	cout<<*rootPtr;
}

template<class ItemType>
void BinaryTree<ItemType>::inOrderUseStack() const //中序遍历
{
	stack<BinaryTreeNode<ItemType>*> tempStack;
	BinaryTreeNode<ItemType> *pTree=rootPtr;
	while(pTree!=nullptr||!tempStack.empty())
	{
		while(pTree!=nullptr)
		{
			tempStack.push(pTree);
			pTree=pTree->leftPtr;
		}
		if(!tempStack.empty())
		{
			pTree=tempStack.top();
			tempStack.pop();
			cout<<*pTree;
			pTree=pTree->rightPtr;//出栈指向右子树
		}

	}
}

template<class ItemType>
BinaryTreeNode<ItemType> * BinaryTree<ItemType>::getTreeRoot() const
{
	return  this->rootPtr;
}
template<class ItemType>
void BinaryTree<ItemType>::preOrderUseStack() const//先序遍历
{
	stack<BinaryTreeNode<ItemType>*> tempStack;
	BinaryTreeNode<ItemType> *pTree=rootPtr;
	while(pTree!=nullptr||!tempStack.empty())
	{
		while(pTree!=nullptr)
		{
			cout<<*pTree;
			tempStack.push(pTree);
			pTree=pTree->leftPtr;
		}
		if(!tempStack.empty())
		{
			pTree=tempStack.top();
			tempStack.pop();
			pTree=pTree->rightPtr;//出栈指向右子树
		}

	}
}

template<class ItemType>
void BinaryTree<ItemType>::postOrderUseStack() const//中序遍历
{
	stack<BinaryTreeNode<ItemType>*> tempStack;
	BinaryTreeNode<ItemType> *pTree=rootPtr;
	BinaryTreeNode<ItemType> *preTree=nullptr;
	while(pTree!=nullptr||!tempStack.empty())
	{
		while(pTree!=nullptr)
		{
			tempStack.push(pTree);
			pTree=pTree->leftPtr;
		}
		pTree=tempStack.top();
		//如果当前节点的右子树为空,或者其右子树已经被访问
		if(pTree->rightPtr==nullptr||pTree->rightPtr==preTree)
		{
			cout<<*pTree;
			preTree=pTree;
			tempStack.pop();
			pTree=nullptr;
		}else
		{
			pTree=pTree->rightPtr;
		}

	}
}

template<class ItemType>
void BinaryTree<ItemType>::clear()
{
	stack<BinaryTreeNode<ItemType>*> tempStack;
	BinaryTreeNode<ItemType> *pTree=rootPtr;
	BinaryTreeNode<ItemType> *preTree=nullptr;
	while(rootPtr!=nullptr||!tempStack.empty())
	{
		while(rootPtr->leftPtr!=nullptr)
		{
			tempStack.push(rootPtr->leftPtr);
		}
		pTree=tempStack.top();
		if(pTree->rightPtr==nullptr&&pTree->rightPtr==preTree)
		{
			tempStack.pop();
			delete pTree;
			preTree=pTree;
			pTree=nullptr;
		}
		else
		{
			pTree=pTree->rightPtr;
		}
	}
	this->rootPtr=nullptr;
}
template<class ItemType>
void BinaryTree<ItemType>::LevelOrder() const
{
	deque<BinaryTreeNode<ItemType>*> tempdq;
	BinaryTreeNode<ItemType> * notePtr=this->rootPtr;
	if( notePtr!=nullptr)
	{
		tempdq.push_back(notePtr);
	}
	while(!tempdq.empty())
	{
		notePtr=tempdq.front();
		cout<<*notePtr;
		if(notePtr->leftPtr!=nullptr)
		{
			tempdq.push_back(notePtr->leftPtr);
		}
		if(notePtr->rightPtr!=nullptr)
		{
			tempdq.push_back(notePtr->rightPtr);
		}
		tempdq.pop_front();
	}
}
template<class ItemType>
int BinaryTree<ItemType>::getHeight(BinaryTreeNode<ItemType> *rootPtr)
{
	if(rootPtr==nullptr)
	{
		return 0;
	}
	int lh=getHeight(rootPtr->leftPtr);
	int rh=getHeight(rootPtr->rightPtr);
	return max(lh,rh)+1;
}
template<class ItemType>
void BinaryTree<ItemType>::mirrorUseRecursion(BinaryTreeNode<ItemType> *rootPtr)
{
	if(rootPtr==nullptr)
	{
		return;
	}
	if(rootPtr->leftPtr==nullptr&&rootPtr->rightPtr==nullptr)
	{
		return;
	}
	BinaryTreeNode<ItemType> *tempPtr=rootPtr->leftPtr;
	rootPtr->leftPtr=rootPtr->rightPtr;
	rootPtr->rightPtr=tempPtr;
	mirrorUseRecursion(rootPtr->leftPtr);
	mirrorUseRecursion(rootPtr->rightPtr);
}
template<class ItemType>
int BinaryTree<ItemType>::getLeafNum(BinaryTreeNode<ItemType> *rootPtr) const
{
	if(rootPtr==nullptr)
	{
		return 0;
	}
	if(rootPtr->leftPtr==nullptr&&rootPtr->rightPtr==nullptr)
	{
		return 1;
	}

	return getLeafNum(rootPtr->leftPtr)+getLeafNum(rootPtr->rightPtr);
}

测试程序:main.cpp

#include"BinaryTree.cpp"
using namespace std;
int main()
{
	BinaryTree<int> btree;
	btree.initBinaryTree();

	cout<<"树高:"<<btree.getHeight(btree.getTreeRoot())<<endl;
	cout<<"树叶子节点数:"<<btree.getLeafNum(btree.getTreeRoot())<<endl;

	cout<<"\n递归先序遍历:";
	btree.preOrderUseRecursion(btree.getTreeRoot());
	cout<<"\n非递归先序遍历:";
	btree.preOrderUseStack();

	cout<<"\n递归中序遍历:";
	btree.inOrderUseRecursion(btree.getTreeRoot());
	cout<<"\n非递归中序遍历:";
	btree.inOrderUseStack();

	cout<<"\n递归后序遍历:";
	btree.postOrderUseRecursion(btree.getTreeRoot());
	cout<<"\n非递后先序遍历:";
	btree.postOrderUseStack();

	cout<<"\n层序遍历:";
	btree.LevelOrder();

	btree.mirrorUseRecursion(btree.getTreeRoot());
	cout<<"\n镜像后层序遍历:";
	btree.LevelOrder();
	system("pause");
	return 0;
}

版权声明:欢迎转载,如有不足之处,恳请斧正。

时间: 2024-10-11 17:59:15

C++实现二叉树相关操作的相关文章

二叉树相关操作

#include <stdio.h> typedef struct BinTree{ int data; struct BinTree *left; struct BinTree *right; }BinTree; void PreOrder(BinTree *root){ if(root == NULL) return; BinTree *p = root; printf("%d\n", p->data); PreOrder(p->left); PreOrde

二叉树的相关操作

#include<stdio.h> #include<malloc.h> #define MAXSIZE 20 typedef char TEelemtype; typedef struct BiTNode{ TEelemtype data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; //队列的方式 typedef struct queueelem { BiTNode* b[MAXSIZE]; int front,rear;

二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)

将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: 1 typedef struct TreeNode{ 2 int data; 3 struct TreeNode *left; 4 struct TreeNode *right; 5 }TreeNode; 2.创建根节点: 1 TreeNode *creatRoot(){ 2 TreeNode * root =(TreeNode *)malloc(sizeof(TreeNode)); 3 if(NULL=

LeetCode:二叉树相关应用

LeetCode:二叉树相关应用 基础知识 617.归并两个二叉树 题目 Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge them into a new binary tree. The merge ru

(二十四)linux新定时器:timefd及相关操作函数

timerfd是Linux为用户程序提供的一个定时器接口.这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,所以能够被用于select/poll的应用场景. 一,相关操作函数 #include <sys/timerfd.h> int timerfd_create(int clockid, int flags); int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itim

linux下进程相关操作

一.定义和理解 狭义定义:进程是正在运行的程序的实例. 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动. 进程的概念主要有两点: 第一,进程是一个实体.每一个进程都有它自己的地址空间,一般情况下,包括文本区域.数据区域和堆栈区域.文本区域存储处理器执行的代码:数据区域存储变量和进程执行期间使用的动态分配的内存:堆栈区域存储着活动过程调用的指令和本地变量. 第二,进程是一个“执行中的程序”.程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们

android DataBase的相关操作(建立表结构和创建表)

先建立一个table的基类: public abstract class DbBaseTable { private static final String TAG = "DbBaseTable"; /** * @return the DB table name */ abstract String getName(); /** * Creates the DB table according to the DB scheme * * @param db */ abstract voi

WebView中的视频全屏的相关操作

最近工作中,基本一直在用WebView,今天就把它整理下: WebView 顾名思义,就是放一个网页,一个看起来十分简单,但是用起来不是那么简单的控件. 首先你肯定要定义,初始化一个webview,其实网上的例子很多,我这里就简单的把一些WebView 中可能会用到的的很重要的属性以及支持全屏播放视频该怎么实现的代码粘出来,直接放到项目中去就行了 <span style="white-space:pre"></span><pre name="co

jQuery学习笔记--JqGrid相关操作 方法列表(上)

1.获得当前列表行数:$("#gridid").getGridParam("reccount"); 2.获取选中行数据(json):$("#gridid").jqGrid('getRowData', id); 3.刷新列表:$(refreshSelector).jqGrid('setGridParam', { url: ''), postData: ''}).trigger('reloadGrid'); 4.选中行:$("#jqGrid