二叉节点及二叉树

二叉节点类BinaryNode<Type>和二叉树类BinaryTree<Type> 及实现:


/***********************二叉节点及二叉树*********************/
#include <iostream>

using namespace std;


//类的前向声明,因为声明二叉树类是二叉节点类的友元类这样访问起来更加方便
template<class Type>
class BinaryTree;


/*1.二叉节点其实包含了关于树的大部分数据结构算法,因为二叉树本身的性质也是体现在那
 * 个根节点BinaryNdoe<Type> *root上所以很多算法比如遍历、递归复制、算高度、算节点
 * 数都是异曲同工的
 */
/*2.实现二叉节点,他的赋值、遍历及其他算法都与多叉节点相似,只要增加left、right之外
 * 的指针就能达到多叉节点的效果
 */
/**********************************二叉节点**********************************/
template<class Type>
class BinaryNode{
	friend class BinaryTree<Type>;
public:
	BinaryNode(): left(NULL),right(NULL){}
	BinaryNode(const Type& value): data(value),left(NULL),right(NULL){}
	//复制当前节点的所有子孙节点
	BinaryNode<Type>* Duplicate();
	int Size(); //以某个节点为起点,返回其下包括自己所有节点数目
	int Height(); //以某个节点为起点,返回其下包括自己所有节点组成树的高度
	void SetData(const Type& data){BinaryNode::data = data;}
	void printData_NLR(); //前序遍历
	void printData_LNR(); //中序遍历
	void printData_LRN(); //后序遍历
	/*填充数据,从当前节点开始,这个函数不是必须的,但是也挺有用
	*的,后面二叉树里也用两种方法实现*/
	void AddValue(const Type& value);
private:
	Type data;
	BinaryNode *left;
	BinaryNode *right;
};


//添加某个值
template<class Type>
void BinaryNode<Type>::AddValue(const Type& value){
	if(this == NULL){
		this = new BinaryNode<Type>(value);
		return;
	}
	if(value > data)
		left->AddValue(value);
	else
		right->AddValue(value);
}


//以某个节点为起点,返回其下包括自己所有节点组成树的高度
template<class Type>
int BinaryNode<Type>::Height(){
	if(this == NULL)
		return 0;
	else
		return 1 + (left->Height() > right->Height() ? left->Height() : right->Height());
}


//复制某个节点和它之后的数据
template<class Type>
BinaryNode<Type>* BinaryNode<Type>::Duplicate(){
	if(this == NULL)
		return NULL;
	BinaryNode<Type>* newNode = new BinaryNode<Type>(data);
	if(left != NULL)  //边界条件1:当前二叉节点左侧叶子节点是NULL
		newNode->left = left->Duplicate();
	if(right != NULL) //边界条件2:当前二叉节点右侧叶子节点是NULL
		newNode->right = right->Duplicate();
	return newNode;
}


template<class Type>
void BinaryNode<Type>::printData_NLR(){ //前序遍历
	if(this == NULL)
		return;
	cout << data << " ";
	if(left != NULL) left->printData_NLR();
	if(right != NULL) right->printData_NLR();
}


template<class Type>
void BinaryNode<Type>::printData_LNR(){ //中序遍历
	if(this == NULL)
		return;
	if(left != NULL) left->printData_LNR();
	cout << data << " ";
	if(right != NULL) right->printData_LNR();
}


template<class Type>
void BinaryNode<Type>::printData_LRN(){ //后序遍历
	if(this == NULL)
		return;
	if(left != NULL) left->printData_LRN();
	if(right != NULL) right->printData_LRN();
	cout << data << " ";
}


/*二叉搜索树,主要还是
 *
 */
/***********************二叉树(还是搜索树插入的时候左小右大)************************************/
template<class Type>
class BinaryTree{
	BinaryNode<Type> *root;
public:
	BinaryTree(): root(NULL){}

	BinaryTree(const BinaryTree<Type>& tree):root(tree.GetRoot()->Duplicate()){}

	BinaryTree(const Type& value){root = new BinaryNode<Type>(value);}

	~BinaryTree(){DeleteTree(root);}

	BinaryNode<Type>* GetRoot() const{return root;}

	void SetRoot(BinaryNode<Type>* newRoot){
		DeleteTree(root);
		root = newRoot;
	}

	//删除以startNode为根的所有节点
	void DeleteTree(BinaryNode<Type> *startNode);

	//复制一棵树
	BinaryTree<Type>* DuplicateTree();

	//用来加入一个新的值,并返回加入的值
	void AddValue(const Type& value);

	//重载一个深度优先的AddValue函数
	void AddValue(BinaryNode<Type> *startNode,const Type& value);

	//以startNode为根节点打印其子节点数据
	void printData_NLR(const BinaryNode<Type> *startNode); //前序遍历
	void printData_LNR(const BinaryNode<Type> *startNode); //中序遍历
	void printData_LRN(const BinaryNode<Type> *startNode); //后续遍历

    const BinaryTree<Type>&
    operator=(const BinaryTree<Type>& T);

//	BinaryNode<Type>* convert(){};  //将二叉数转换成链表
};


template<class Type>
const BinaryTree<Type>&
BinaryTree<Type>::operator=(const BinaryTree<Type>& T){
	if(this != &T){
		DeleteTree(root);
		if(T.root != NULL) root = T.root->Duplicate();
	}
	return *this;
}


template<class Type>
void BinaryTree<Type>::DeleteTree(BinaryNode<Type> *startNode){
	if(startNode != NULL){
		DeleteTree(startNode->left);
		DeleteTree(startNode->right);
		delete startNode;
	}
}


//复制一棵树
template<class Type>
BinaryTree<Type>* BinaryTree<Type>::DuplicateTree(){
	BinaryTree<Type> *newTree = new BinaryTree<Type>();
	newTree->root = root->Duplicate();
	return newTree;
}


template<class Type>
void BinaryTree<Type>::AddValue(const Type& value){
	if(root == NULL){
		root = new BinaryNode<Type>(value);
	}else{
		BinaryNode<Type> *node = root;
		while(1){
			if(value > node->data){
				if(node->right == NULL){			//此时node已经定位在空的节点处了
					node->right = new BinaryNode<Type>(value);
					break;
				}else{
					node = node->right;
				}
			}else{
				if(node->left == NULL){
					node->left = new BinaryNode<Type>(value);
					break;
				}else{
					node = node->left;
				}
			}
		}
	}
}


template<class Type>
void BinaryTree<Type>::AddValue(BinaryNode<Type> *startNode,const Type& value){
	if(startNode == NULL){
		root = new BinaryNode<Type>(value);
		return;
	}
	if(value > startNode->data){
		if(startNode->right == NULL){
			startNode->right = new BinaryNode<Type>(value);
		}
		else
			AddValue(startNode->right,value);
	}else{
		if(startNode->left == NULL){
			startNode->left = new BinaryNode<Type>(value);
		}
		else
			AddValue(startNode->left,value);
	}
}


//前序遍历
template<class Type>
void BinaryTree<Type>::printData_NLR(const BinaryNode<Type> *startNode){
	if(startNode == NULL){
		return;
	}else{
		cout << startNode->data << " ";
		printData_NLR(startNode->left);
		printData_NLR(startNode->right);
	}
}


//中序遍历
template<class Type>
void BinaryTree<Type>::printData_LNR(const BinaryNode<Type> *startNode){
	if(startNode == NULL){
		return;
	}else{
		printData_LNR(startNode->left);
		cout << startNode->data << " ";
		printData_LNR(startNode->right);
	}
}


//后序遍历
template<class Type>
void BinaryTree<Type>::printData_LRN(const BinaryNode<Type> *startNode){
	if(startNode == NULL){
		return;
	}else{
		printData_LRN(startNode->left);
		printData_LRN(startNode->right);
		cout << startNode->data << " ";
	}
}

测试代码:

int main(){
	BinaryTree<int> tree;

	/********************填充数据(从根节点开始填)*****************************/
	//从树的根节点开始插入,插入方式像BSTree左小右大
	tree.AddValue(tree.GetRoot(),7);
	tree.AddValue(tree.GetRoot(),4);
	tree.AddValue(tree.GetRoot(),10);
	tree.AddValue(tree.GetRoot(),1);
	tree.AddValue(tree.GetRoot(),5);
	tree.AddValue(tree.GetRoot(),-1);
	tree.AddValue(tree.GetRoot(),2);
	tree.AddValue(tree.GetRoot(),9);
	tree.AddValue(tree.GetRoot(),13);
	tree.AddValue(tree.GetRoot(),12);
	tree.AddValue(tree.GetRoot(),11);
	tree.AddValue(tree.GetRoot(),14);
	/*********************************************************/

	//原先的树
	cout << "原先的树" << endl;
	tree.printData_LNR(tree.GetRoot());
	cout << endl << endl;

	//新建的树1 测试DuplicateTree()函数
	cout << "新建的newTree1 测试tree.DuplicateTree()函数" << endl;
	BinaryTree<int> newTree1;
	newTree1.SetRoot(tree.DuplicateTree()->GetRoot());
	newTree1.GetRoot()->printData_LNR();
	cout << endl << endl;

	//新建的树2 测试等号重载
	cout << "新建的newTree2 测试等号重载" << endl;
	BinaryTree<int> newTree2;
	newTree2 = tree;
	newTree2.GetRoot()->printData_LNR();
	cout << endl << endl;
	return 0;
}

测试输出:

都是按照LNR 即中序遍历输出:


二叉节点及二叉树_第1张图片

你可能感兴趣的:(数据结构,算法,测试,tree,null,delete)