关闭

二叉树三种遍历方式,有先序,中序或者后序,中序恢复二叉树等操作

标签: 二叉树遍历
267人阅读 评论(0) 收藏 举报
分类:
//头文件
//BinaryTreeNode.h
#ifndef BINARYTREENODE_H
#define BINARYTREENODE_H
template<typename T>
class BinaryTreeNode{
public:
	T data;
	BinaryTreeNode<T>* leftChild;
	BinaryTreeNode<T>* rightChild;
	BinaryTreeNode(){

	}
	BinaryTreeNode(const T& val, BinaryTreeNode<T>* str, BinaryTreeNode<T>* ptr) :data(val), leftChild(str), rightChild(ptr){

	}
};
#endif
//BinaryTree.h
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include"BinaryTreeNode.h"
#include<iostream>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
template<typename T>
class BinaryTree{
private:
	BinaryTreeNode<T>* root;
public:
	BinaryTree();
	~BinaryTree();
	//一下为二叉树的基本操作
	void creat();
	bool isEmpty();
	BinaryTreeNode<T>* getRoot();
	T reValue(BinaryTreeNode<T>* str)const;
	void reSet(BinaryTreeNode<T>* str, const T& val);
	void Deep()const;
	//输出操作
	void PrintInOrder(BinaryTreeNode<T>* str);
	void PrintLevelOrder();
	void PrintPostOrder(BinaryTreeNode<T>* str);
	//该函数是模拟先序,中序和后序,中序恢复出二叉树的操作
	void simulate();
private:
	//有中序序列和先序序列确定二叉树,递归形式的算法
	void DefineBinaryTree(BinaryTreeNode<T>* &str,char* preOrder,char* midOrder,int length);
	void DefineBinaryTree(char* preOrder, char* midOrder);
	//有后序序列,中序序列确定二叉树
	void DefineBinaryTreePost(BinaryTreeNode<T>* &str,char* postOrder,char* midOrder,int length);
	void DefineBinaryTreePost(char* postOrder, char* midOrder);
	//清空树
	void makeEmpty(BinaryTreeNode<T>* &str);
private:
	int deep(BinaryTreeNode<T>* str)const;
	void CreatBiTree(BinaryTreeNode<T>* &str);
	//非递归方法求树的深度
	int deepPrivate()const;
private:
	//该函数是用非递归方法,在给出先序和后序数列时,求出二叉树,该函数是为void DefineBinaryTree(char* preOrder, char* midOrder);
	//函数服务的
	int posChar(char ch, char* str);
};
template<typename T>
int BinaryTree<T>::posChar(char ch, char* str)
{
	if (strlen(str) == 0)
	{
		cout << "the char* is empty" << endl;
		exit(true);
	}
	int i = 0;
	while (str[i] != '\0')
	{
		if (ch == str[i])
		{
			return i;
		}
		i++;
	}
	return -1;
}
template<typename T>
void BinaryTree<T>::DefineBinaryTree(char* preOrder, char* midOrder)
{
	if (strlen(preOrder) == 0 || strlen(midOrder) == 0)
	{
		this->root = NULL;
		return;
	}
	//记录每个与先序中节点对应的后序中的节点的位置
	int pos;
	//position,node两个栈存放的是pos,和生成的每个节点
	stack<int>position;
	stack<BinaryTreeNode<T>*>node;
	//str,ptr用于生成节点
	BinaryTreeNode<T>* str = NULL;
	BinaryTreeNode<T>* ptr = NULL;
	str = new BinaryTreeNode<T>(preOrder[0], NULL, NULL);
	this->root = str;
	pos = posChar(preOrder[0], midOrder);
	position.push(pos);
	node.push(str);
	int i = 1;
	while (preOrder[i] != '\0')
	{
		pos = posChar(preOrder[i], midOrder);
		if (pos == -1)
		{
			cout << "the match is error" << endl;
			exit(true);
		}
		str = new BinaryTreeNode<T>(preOrder[i], NULL, NULL);
		if (pos < position.top())
		{
			//当num < position.top()时,则该节点是左节点
			ptr = node.top();
			ptr->leftChild = str;
			node.push(str);
			position.push(pos);
		}
		else
		{
			while (!position.empty() && pos > position.top())
			{
				ptr = node.top();
				position.pop();
				node.pop();
			}
			ptr->rightChild = str;
			node.push(str);
			position.push(pos);
		}
		i++;
	}
}
template<typename T>
void BinaryTree<T>::simulate()
{
	/*char preOrder[100];*/
	char postOrder[100];
	char midOrder[100];
	cout << "input the postOrder: ";
	/*cin >> preOrder;*/
	cin >> postOrder;
	//在这里对后序序列进行处理,将整个字符数组的顺序颠倒过来
	char str[100];
	int j = 0;
	int count = strlen(postOrder);
	for (int i = 0; i < count; j++, i++)
	{
		str[j] = postOrder[i];
	}
	str[j] = '\0';
	int i = 0;
	for (j = strlen(str) - 1; i < count, j >= 0; j--, i++)
	{
		postOrder[i] = str[j];
	}
	postOrder[i] = '\0';
	cout << "input the midOrder: ";
	cin >> midOrder;
	int length = strlen(midOrder);
	/*this->DefineBinaryTree(this->root,preOrder,midOrder,length);*/
	/*this->DefineBinaryTree(preOrder, midOrder);*/
	/*this->DefineBinaryTreePost(this->root, postOrder, midOrder,length);*/
	this->DefineBinaryTreePost(postOrder, midOrder);
}
template<typename T>
void BinaryTree<T>::DefineBinaryTree(BinaryTreeNode<T>* &str, char* preOrder, char* midOrder, int length)
{
	if (length == 0)
	{
		str = NULL;
		return;
	}
	str = new BinaryTreeNode<T>(*preOrder, NULL, NULL);
	char* pStr = strchr(midOrder, str->data);
	if (pStr == NULL)
	{
		cout << "the midOrder string is wrong" << endl;
		exit(true);
	}
	int leftTreeLength = strlen(midOrder) - strlen(pStr);
	int rightTreeLength = length - leftTreeLength - 1;
	DefineBinaryTree(str->leftChild, preOrder + 1, midOrder, leftTreeLength);
	DefineBinaryTree(str->rightChild, preOrder + leftTreeLength + 1, pStr + 1, rightTreeLength);
}
template<typename T>
void BinaryTree<T>::DefineBinaryTreePost(BinaryTreeNode<T>* &str, char* postOrder, char* midOrder, int length)
{
	if (length==0)
	{
		str = NULL;
		return;
	}
	str = new BinaryTreeNode<T>(*postOrder, NULL, NULL);
	char* pStr = strchr(midOrder, str->data);
	if (pStr == NULL)
	{
		cout << "the midOrder is wrong" << endl;
		exit(true);
	}
	//这里的字符串处理有错误
	int leftLength = strlen(midOrder) - strlen(pStr);
	int rightLength = length - leftLength - 1;
	DefineBinaryTreePost(str->leftChild, postOrder + rightLength + 1, midOrder, leftLength);
	DefineBinaryTreePost(str->rightChild, postOrder + 1, midOrder + leftLength + 1, rightLength);
}
template<typename T>
void BinaryTree<T>::DefineBinaryTreePost(char* postOrder, char* midOrder)
{
	//在该函数中的postOrder序列是顺序已经被颠倒之后的序列
	if (strlen(postOrder) == 0 || strlen(midOrder) == 0)
	{
		this->root = NULL;
		return;
	}
	int pos;
	stack<int>position;
	stack<BinaryTreeNode<T>*>node;
	BinaryTreeNode<T>* str = NULL;
	BinaryTreeNode<T>* ptr = NULL;
	str = new BinaryTreeNode<T>(postOrder[0], NULL, NULL);
	this->root = str;
	pos = posChar(str->data, midOrder);
	node.push(str);
	position.push(pos);
	int i = 1;
	while (postOrder[i] != '\0')
	{
		pos = posChar(postOrder[i], midOrder);
		if (pos == -1)
		{
			cout << "the midOrder is error" << endl;
			exit(true);
		}
		str = new BinaryTreeNode<T>(postOrder[i], NULL, NULL);
		if (pos < position.top())
		{
			ptr = node.top();
			ptr->leftChild = str;
			node.push(str);
			position.push(pos);
		}
		else
		{
			while (!position.empty() && pos>position.top())
			{
				ptr = node.top();
				node.pop();
				position.pop();
			}
			ptr->rightChild = str;
			node.push(str);
			position.push(pos);
		}
		i++;
	}
}
template<typename T>
int BinaryTree<T>::deepPrivate()const
{
	if (this->root == NULL)
		return 0;
	BinaryTreeNode<T>* p = this->root;
	queue<BinaryTreeNode<T>*>que;
	que.push(p);
	int deepth = 0;
	while (!que.empty())
	{
		deepth++;
		//每次在循环开始之前,都要获得cur=0,和curQueSize的值
		//curQueSize记录了每一层中的节点数目,当所有的这一层的节点的左右孩子全部都进入
		//队列后退出循环
		int cur = 0;
		int curQueSize = que.size();
		while (cur < curQueSize)
		{
			cur++;
			//每次都要保证在队列中的节点为同一层的节点
			p = que.front();
			que.pop();
			if (p->leftChild)
				que.push(p->leftChild);
			if (p->rightChild)
				que.push(p->rightChild);
		}
	}
	return deepth;
}
template<typename T>
void BinaryTree<T>::Deep()const
{
	cout << "the deep is " << this->deepPrivate() << " of the tree" << endl;
}
template<typename T>
int BinaryTree<T>::deep(BinaryTreeNode<T>* str)const
{
	if (str == NULL)
		return 0;
	int h1, h2;
	h1 = deep(str->leftChild);
	h2 = deep(str->rightChild);
	return h1 > h2 ? h1 + 1 : h2 + 1;
}
template<typename T>
bool BinaryTree<T>::isEmpty()
{
	if (this->root == NULL)
		return true;
	return false;
}
template<typename T>
BinaryTree<T>::BinaryTree()
{
	this->root = NULL;
}
template<typename T>
BinaryTree<T>::~BinaryTree()
{
	this->makeEmpty(this->root);
}
template<typename T>
BinaryTreeNode<T>* BinaryTree<T>::getRoot()
{
	if (this->isEmpty())
	{
		cout << "the tree is empty" << endl;
		exit(true);
	}
	return this->root;
}
template<typename T>
T BinaryTree<T>::reValue(BinaryTreeNode<T>* str)const
{
	if (str == NULL)
	{
		cout << "the point is null" << endl;
		exit(true);
	}
	return str->data;
}
template<typename T>
void BinaryTree<T>::reSet(BinaryTreeNode<T>* str, const T& val)
{
	if (str == NULL)
	{
		cout << "the point is null" << endl;
		exit(true);
	}
	str->data = val;
}
template<typename T>
void BinaryTree<T>::makeEmpty(BinaryTreeNode<T>* &str)
{
	if (str)
	{
		makeEmpty(str->leftChild);
		makeEmpty(str->rightChild);
		delete str;
	}
	str = NULL;
}
template<typename T>
void BinaryTree<T>::creat()
{
	this->CreatBiTree(root);
}
template<typename T>
void BinaryTree<T>::CreatBiTree(BinaryTreeNode<T>* &str)
{
	T value;
	if (root == NULL)
	{
		cout << "the root data is: ";
	}
	cin >> value;
	if (value == '#')
	{
		str = NULL;
		return;
	}
	else
	{
		str = new BinaryTreeNode<T>(value, NULL, NULL);
		cout << "input the " << str->data << " leftchild: ";
		CreatBiTree(str->leftChild);
		cout << "input the " << str->data << " rightchild: ";
		CreatBiTree(str->rightChild);
	}
}
template<typename T>
void BinaryTree<T>::PrintInOrder(BinaryTreeNode<T>* str)
{
	if (str != NULL)
	{
		PrintInOrder(str->leftChild);
		cout << str->data << " ";
		PrintInOrder(str->rightChild);
	}
	else
		return;
}
template<typename T>
void BinaryTree<T>::PrintLevelOrder()
{
	BinaryTreeNode<T>* p = this->root;
	queue<BinaryTreeNode<T>*>nodeQue;
	if (p != NULL)
		nodeQue.push(p);
	while (!nodeQue.empty())
	{
		p = nodeQue.front();
		nodeQue.pop();
		cout << p->data << " ";
		if (p->leftChild)
			nodeQue.push(p->leftChild);
		if (p->rightChild)
			nodeQue.push(p->rightChild);
	}
	cout << endl;
}
template<typename T>
void BinaryTree<T>::PrintPostOrder(BinaryTreeNode<T>* str)
{
	if (str != NULL)
	{
		PrintPostOrder(str->leftChild);
		PrintPostOrder(str->rightChild);
		cout << str->data << " ";
	}
}
#endif
//主函数
#include"BinaryTree.h"
int main(int argc, char argv[])
{
	BinaryTree<char>tree;
	tree.creat();
	tree.PrintInOrder(tree.getRoot());
	cout << endl;
	tree.PrintLevelOrder();
	tree.PrintPostOrder(tree.getRoot());
	cout << endl;
	tree.Deep();
	tree.simulate();
	tree.PrintPostOrder(tree.getRoot());
	cout << endl;
	tree.Deep();
	return 0;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:17978次
    • 积分:892
    • 等级:
    • 排名:千里之外
    • 原创:74篇
    • 转载:0篇
    • 译文:0篇
    • 评论:9条
    文章分类
    最新评论