类模板实现的基本二叉树

关于二叉树的基本知识还是有必要去了解的,比如根据二叉树写出三种遍历,以及根据给出的遍历写出其他方式的遍历和重构二叉树等,这些知识点还是很有意思的大笑,下面的代码很多都是参考网上的,我这里贴出来主要是作为我学习数据结构的一些总结吧

首先是树节点的定义:

template<class Entry>
struct Binary_node
{
	Entry data;
	Binary_node<Entry>* left;
	Binary_node<Entry>* right;
	Binary_node();
	Binary_node(const Entry &x);
};

这个没啥说的,一看就懂

下面是二叉树的类函数

template<class Entry>
class Binary_tree
{
public:
	Binary_tree():root(NULL){};
	~Binary_tree();
/*	Binary_tree();*/
	bool empty() const;
	void preorder(void (*visit)(Entry &));
	void inorder(void (*visit)(Entry &));
	void postorder(void (*visit)(Entry &));
	//Binary_tree大小
	int size() const;
	int height() const;
	void clear();
	void insert(const Entry& x);
	void reverse();
	Binary_tree(const Binary_tree<Entry>&original);
	Binary_tree & operator=(const Binary_tree<Entry>&original);
	const Binary_node<Entry>* get_root() const;
	//一些递归辅助函数
private:	
	int recursive_size(const Binary_node<Entry>*root) const;
	int recursive_height(const Binary_node<Entry>*root) const;
	void equal(Binary_node<Entry>*&sub_root,const Binary_node<Entry>*orig_node);
	void recursive_reverse(Binary_node<Entry> * & sub_root);
	void recursive_clear(Binary_node<Entry> * & sub_root);
	void recursive_insert(Binary_node<Entry> * & sub_root, const Entry& x);
	void recursive_inorder(Binary_node<Entry> * sub_root, void (*visit)(Entry &));
	void recursive_preorder(Binary_node<Entry> * sub_root, void (*visit)(Entry &));
	void recursive_postorder(Binary_node<Entry> * sub_root, void (*visit)(Entry &));
protected:
	Binary_node<Entry>* root;

};

操作二叉树的一个显著特点就是大量使用了递归,基本上每个操作都编写了相应的递归函数并将其声明为private,这样可以获得更好的封装性

注意到有三个函数传递的指针的引用

void recursive_reverse(Binary_node<Entry> * & sub_root);
void recursive_clear(Binary_node<Entry> * & sub_root);
void recursive_insert(Binary_node<Entry> * & sub_root, const Entry& x);

这些函数都是要修改protected保护下的 root,传递引用于直接传地址的区别是,引用传递的就是root本身;传递Binary_node<Entry> * sub_root

其实传递的是root的副本,如果只是要读取数据那么这样做没问题,比如遍历函数。

下面继续贴代码吐舌头

#ifndef BINARY_TREE_CPP_X
#define BINARY_TREE_CPP_X
#include "Binary_tree.h"
//结点构造函数
template<class Entry>
Binary_node<Entry>::Binary_node()
{
	left = right = NULL;
}
template<class Entry>
Binary_node<Entry>::Binary_node(const Entry &x)
{
	left = right = NULL;
	data = x;
}
template<class Entry>
Binary_tree<Entry>::Binary_tree(const Binary_tree<Entry>&original)
{
	root = original.get_root();
}
template<class Entry>
void Binary_tree<Entry>::recursive_inorder(Binary_node<Entry>*sub_root, void(*visit)(Entry&))
{//中序遍历的递归函数
	if(sub_root!=NULL)
	{
		recursive_inorder(sub_root->left, visit);
		(*visit)(sub_root->data);
		recursive_inorder(sub_root->right, visit);
	}
}
template<class Entry>
void Binary_tree<Entry>::inorder(void (*visit)(Entry&))
{//中序遍历
	recursive_inorder(root, visit);
}

template<class Entry>
void Binary_tree<Entry>::recursive_postorder(Binary_node<Entry>*sub_root, void (*visit)(Entry&))
{//后序遍历的递归函数
	if (sub_root!=NULL)
	{
		recursive_postorder(sub_root->left, visit);
		recursive_postorder(sub_root->right, visit);
		(*visit)(sub_root->data);
	}
}
template<class Entry>
void Binary_tree<Entry>::postorder(void (*visit)(Entry&))
{//后序遍历
	recursive_postorder(root, visit);
}

template<class Entry>
void Binary_tree<Entry>::recursive_preorder(Binary_node<Entry>*sub_root, void (*visit)(Entry&))
{//先序遍历的递归函数
	if (sub_root!=NULL)
	{
		(*visit)(sub_root->data);
		recursive_preorder(sub_root->left, visit);
		recursive_preorder(sub_root->right, visit);
	}
}
template<class Entry>
void Binary_tree<Entry>::preorder(void (*visit)(Entry&))
{//先序遍历
	recursive_preorder(root, visit);
}

//return tree height, if only one node then return 1
template<class Entry>
int Binary_tree<Entry>::height() const
{
	return recursive_height(root);
}
#define max MAX
template<class Comparable>
Comparable MAX(const Comparable& a, const Comparable& b)
{
	return a > b ? a : b;
}
template<class Entry>
int Binary_tree<Entry>::recursive_height(const Binary_node<Entry>*root) const
{
	if(root == NULL)
		return 0;
	else
		return 1 + max(recursive_height(root->left) , recursive_height(root->right)) ;
}
#undef max

//return the size of tree
template<class Entry>
int Binary_tree<Entry>::size() const
{
	return recursive_size(root);
}
template<class Entry>
int Binary_tree<Entry>::recursive_size(const Binary_node<Entry>*root) const
{
	if(root == NULL)
		return 0;
	else
		return 1 + recursive_size(root->left) + recursive_size(root->right) ;
}
//the tree is empty ?
template<class Entry>
bool Binary_tree<Entry>::empty() const
{
	return root == NULL;
}
//insert x to the tree
template<class Entry>
void Binary_tree<Entry>::insert(const Entry& x)
{
	recursive_insert(root, x);
}
//the recursive function of insert, 
//insert x in the less height side, 
//if both sides are same height then insert to the left
//第一个参数必须使用引用否则插入失败,而其他不涉及数据改动的函数则不需要
//引用传参时不会发生值拷贝,如果不加引用,会先在函数的栈空间拷贝一个root,但当函数
//结束时这个拷贝就会被销毁,所以会导致插入失败
template<class Entry>
void Binary_tree<Entry>::recursive_insert(Binary_node<Entry>*&sub_root, const Entry& x)
{
	if(sub_root == NULL)
	{
		Binary_node<Entry>* ins_data = new Binary_node<Entry>(x);
		sub_root = ins_data;
		return;
	}
	else
	{
		if(recursive_height(sub_root->left) > recursive_height(sub_root->right))
			recursive_insert(sub_root->right, x);
		else
			recursive_insert(sub_root->left, x);
	}
}
//destuctor
template<class Entry>
Binary_tree<Entry>::~Binary_tree()
{
 	clear();
}
template<class Entry>
void Binary_tree<Entry>::clear()
{
	recursive_clear(root);
}
//recursive function for destroy tree
template<class Entry>
void Binary_tree<Entry>::recursive_clear(Binary_node<Entry>*&sub_root)
{//两个版本都OK
#if 0
	if(sub_root != NULL)
	{
		recursive_clear(sub_root->left);
		recursive_clear(sub_root->right);
		delete sub_root;
		sub_root = NULL;
	}
#else
	if(sub_root->left!=NULL)
		recursive_clear(sub_root->left);
	if(sub_root->right!=NULL)
		recursive_clear(sub_root->right);
	delete sub_root;
	sub_root = NULL;
#endif
}
//get the root
template<class Entry>
const Binary_node<Entry>* Binary_tree<Entry>::get_root() const
{
	return root;
}
//deep copy
template<class Entry>
Binary_tree<Entry>& Binary_tree<Entry>::operator =(const Binary_tree<Entry>&original)
{
	equal(root, original.get_root());
	return *this;
}
template<class Entry>
void Binary_tree<Entry>::equal(Binary_node<Entry>*&sub_root,const Binary_node<Entry>*orig_node)
{
	if(empty())
		sub_root = new Binary_node<Entry>(orig_node->data);
	if(orig_node->left!=NULL)
	{
		sub_root->left = new Binary_node<Entry>(orig_node->left->data);
		equal(root->left, orig_node->left);
	}
	if(orig_node->right!=NULL)
	{
		sub_root->right = new Binary_node<Entry>(orig_node->right->data);
		equal(root->right, orig_node->right);
	}
}
//reverse the binary tree,  exchange left and right
template<class Entry>
void Binary_tree<Entry>::reverse()
{
	recursive_reverse(root);
}
template<class Entry>
void Binary_tree<Entry>::recursive_reverse(Binary_node<Entry> * & sub_root)
{
	if(sub_root!=NULL)
	{
		Binary_node<Entry>* temp = NULL;
		temp = sub_root->left;
		sub_root->left = sub_root->right;
		sub_root->right = temp;
		recursive_reverse(sub_root->left);
		recursive_reverse(sub_root->right);
	}
}
#endif

要说明一下insert和reverse这两个函数,

insert的规则是:如果root为空,新元素插入到根节点,否则把它插入到两颗子树中较短的一颗,

如果两颗子树具有同样的高度就插入到左子树中

reverse的规则如下图:


最后是测试代码:

#include <iostream>
#include "Binary_tree.h"
using namespace std;
void print( int& x);
int main()
{
	Binary_tree<int> dd;
	dd.insert(3);
	dd.insert(2);
	dd.insert(5);
	dd.insert(8);
	dd.insert(9);
	dd.insert(1);
	Binary_tree<int> ww;
	ww = dd;
	ww.insert(10);
	ww.insert(7);
	cout<<"preorder:";
	dd.preorder(print);
	cout<<endl;
	cout<<"preorder:";
	ww.preorder(print);
	cout<<endl;
	dd.reverse();
	cout<<"preorder:";
	dd.preorder(print);
	cout<<endl;	
	system("pause");
	return 0;
}
void print( int& x)
{
	cout<<x<<" ";
}

代码的链接http://download.youkuaiyun.com/detail/mjlsuccess/6510141


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值