C++二叉树的实现

实现了简单的通过字符串构造二叉树


//BinaryTree.h

#pragma once
//类型定义
//2016 .3 .2

#include<queue>
#include<cassert>
using namespace std;
#ifndef NULL
#define NULL (0)
#endif
#pragma once
enum ChildType {LEFT,RIGHT};
template<class T>
struct BinaryTreeNode   //结点定义
{
public:
	BinaryTreeNode(T t=NULL)
	:_data(t)
	,lchild(NULL)
	, rchild(NULL)
	{}
	T _data;
	BinaryTreeNode * lchild;
	BinaryTreeNode * rchild;


	析构,二叉树类可以递归/迭代的调用结点的析构函数来析构
	//~BinaryTreeNode()
	//{
	//	if (lchild != NULL)
	//		delete lchild;
	//	if (rchild != NULL)
	//		delete rchild;
	//}

	BinaryTreeNode(const BinaryTreeNode& bNode)   //拷贝构造  
		:lchild(NULL)
		, rchild(NULL)
		, _data(bNode._data)
	{}

};

template<class T>
class BinaryTree   //二叉树定义
{
public:

	BinaryTree()   //构造函数
		:proot(NULL)
	{}
	
	BinaryTree(char * str)   //构造函数  只适用于int 或者char 等
	{
		//proot = _CreateTree(str);
		cerr << "暂时不能创建该类型的二叉树";
		system("pause");
		exit(1);
	}

	BinaryTreeNode<T> * FindPointer(T e)   //找出指向一个元素结点的指针 中序遍历
	{
		BinaryTreeNode<T> a(e);
	    return	InOrderTraverse(a);
	}
	
	void PreOrderTraverse()   //前序遍历
	{
		_PreOrderTraverse(proot);
	}

    void InOrderTraverse()   //中序遍历
	{
		_InOrderTraverse(proot);
	}
	BinaryTreeNode<T>* InOrderTraverse(BinaryTreeNode<T> & e)   //中序遍历查找元素指针
	{
		return _InOrderTraverse(proot, e);
	}

	void LevelOrderTraverse()    //层序遍历
	{
		_LevelOrderTraverse(proot);
	}
	//拷贝构造  使用前序遍历生成
	BinaryTree(const BinaryTree<T> & BiTree)
	{
		//递归遍历构造吧
		this->proot= _CopyPreOrderTraverse(BiTree.proot);
	}

	void InsertChild(BinaryTreeNode<T> * parent, ChildType LR, T child)
	{
		//插入单个元素
		BinaryTreeNode<T>* newNode = new BinaryTreeNode<T>(child);

		InsertChild(parent, LR, newNode);  //直接复用函数

	}

	void InsertChild(BinaryTreeNode<T> * parent, ChildType LR, BinaryTreeNode<T> * child)   //插入
	{
		//child要求不能有右子树
		//将child指向的结点插入到parent的左或者右孩子.
		//若要插入的结点已经有该孩子,则将该孩子子树挪到child的右子树

		assert(parent);

		if (LR == LEFT)   //左
		{
			if (parent->lchild != NULL)
			{
				BinaryTreeNode<T>* tmp = parent->lchild;   //保存左子树
				parent->lchild = child;
				child->rchild = tmp;
			}
			else   //不存在左子树,则直接插入
			{
				parent->lchild = child;
			}
		}
		else   //  右
		{
			if (parent->rchild != NULL)
			{
				BinaryTreeNode<T>* tmp = parent->rchild;   //保存右子树
				parent->rchild = child;
				child->rchild = tmp;
			}
			else   //不存在右子树,则直接插入
			{
				parent->rchild = child;
			}
		}
	}

	BinaryTreeNode<T> * Visit(BinaryTreeNode<T> * root, BinaryTreeNode<T> & E)   //访问对比结点  也就是查找
	{
		if (root->_data == E._data)
			return root;
		else
			return NULL;
	}

	void Visit(BinaryTreeNode<T> & e)   //访问结点
	{
		cout << e._data << endl;
	}

	int Size()   //树总结点数
	{
		return _Size(proot);
	}

	int Depth()   //深度
	{
		return _Depth(proot);
	}

	~BinaryTree()  
	{
		_Destory(proot);//递归释放
	}

protected:

	void _PreOrderTraverse(BinaryTreeNode<T> * root)   // 前序访问
	{
		if (root != NULL)
		{
			Visit(*root);
			_PreOrderTraverse(root->lchild);
			_PreOrderTraverse(root->rchild);
		}
	}

	BinaryTreeNode<T> * _CopyPreOrderTraverse(BinaryTreeNode<T> * root)   // 前序拷贝构造一个树
	{
		BinaryTreeNode<T> * node = NULL;
		if (root != NULL)
		{
			node= new BinaryTreeNode<T>(*root);
			node->lchild= _CopyPreOrderTraverse(root->lchild);
			node->rchild= _CopyPreOrderTraverse(root->rchild);
		}

		return node;
	}

	BinaryTreeNode<T>* _InOrderTraverse(BinaryTreeNode<T> * root, BinaryTreeNode<T> & e)
	{
		if (root == NULL)
			return NULL;
		_InOrderTraverse(root->lchild, e);
		auto re = Visit(root, e);
		if (re != NULL)
			return re;
		_InOrderTraverse(root->rchild, e);
	}


	void _InOrderTraverse(BinaryTreeNode<T> * root)
	{
		if (root == NULL)
			return;
		_InOrderTraverse(root->lchild);
		Visit(*root);
		_InOrderTraverse(root->rchild);
	}

	void _Destory( BinaryTreeNode<T> * root)
	{
		if (root != NULL)
		{
			_Destory(root->lchild);
			_Destory(root->rchild);
			delete root;
		}	
	}

	BinaryTreeNode<T>* _CreateTree(char * &str)   //递归创建
	{
		BinaryTreeNode<T> * node=NULL;
		
		if ((*str) != '\0' && (*str) != '#')
		{
			node = new BinaryTreeNode<T>((*str - '0'));
			node->lchild = _CreateTree(++str);
			node->rchild = _CreateTree(++str);
		}

		return node;
	}


	void _LevelOrderTraverse(BinaryTreeNode<T> * root)
	{
		if (root == NULL)
			return;
		queue<BinaryTreeNode<T>*> q;
		q.push(root);
		BinaryTreeNode<T> * cur = NULL;
		while (!q.empty())
		{
			cur = q.front();
			Visit(*cur);
			q.pop();
			if (cur->lchild) q.push(cur->lchild);
			if (cur->rchild) q.push(cur->rchild);
		}
	}

	int _Size(BinaryTreeNode<T> * root)
	{
		if (root == NULL)
			return 0;
		return _Size(root->lchild) + _Size(root->rchild)+1;
	}

	int _Depth(BinaryTreeNode<T> * root)
	{
		if (root == NULL)
			return 0;
		auto left = root->lchild;
		auto right = root->rchild;

		int ld;
		int rd;

		return ((ld = _Depth(left)) > (rd = _Depth(right)) ? ld : rd)+1;
		
	}

protected:
	
	BinaryTreeNode<T> * proot;  //指向根的指针
};

template<>   //特化
BinaryTree<int>::BinaryTree(char * str)   //构造函数
	{
		proot = _CreateTree(str);
	}


template<>   //特化
BinaryTree<char>::BinaryTree(char * str)   //构造函数
{
	proot = _CreateTree(str);
}

template<>   //特化
BinaryTree<size_t>::BinaryTree(char * str)   //构造函数
{
	proot = _CreateTree(str);
}

template<>   //特化
BinaryTree<long long>::BinaryTree(char * str)   //构造函数
{
	proot = _CreateTree(str);
}

template<>   //特化
BinaryTree<long>::BinaryTree(char * str)   //构造函数
{
	proot = _CreateTree(str);
}


测试用例:Main.cpp


#include<queue>
#include"BinaryTree.h"
#include<iostream>
using namespace std;

void Test1()
{
	char * str = "123##4##56##";
	BinaryTree<int> b(str);

	//b.Print();

	//b.LevelOrderTraverse();

	//b.InOrderTraverse();
	cout <<"depth:"<< b.Depth() << endl;
	cout<<"size:"<<b.Size()<<endl;

	//

	auto p = b.FindPointer(5);  //插入的指针

	b.InsertChild(p, RIGHT, 7);

	cout << "b:中序遍历" << endl;
	b.InOrderTraverse();
	cout << "b:前序遍历" << endl;

	b.PreOrderTraverse();

	//试试拷贝构造
	BinaryTree<int> c(b);
	cout<<"c:Depth:"<<c.Depth()<<endl;
	cout << "c:Size:" << c.Size() << endl;
	cout << "前序遍历:" << endl;
	c.PreOrderTraverse();
	cout << "中序遍历:" << endl;
	c.InOrderTraverse();

}

int main()
{
	Test1();
	system("pause");
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值