二叉树三种遍历方式,有先序,中序或者后序,中序恢复二叉树等操作
2015-11-19 16:41
585 查看
//头文件 //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; }
相关文章推荐
- [原]Eclipse启动报错:An internal error occurred during: "Building workspace".
- 一路两输入正与门SN74AHC1G08学习
- 《高性能网站建设指南》读书笔记
- SSH框架搭建
- 多工程批量打包
- ArcGIS中QueryTask,FindTask,IndentifyTask 之间的区别
- ListView的使用----ArrayAdapter与SimpleAdapter
- zigbee网关 zstack CC2530添加iic温度传感器lm75a
- Hadoop系列二:启动HDFS和YARN过程日志
- Eclipse用法和技巧二十四:当git遇上eclipse
- T-SQL动态查询(2)——关键字查询
- Drozer安装使用及报错解决办法
- android ListView详解
- T-SQL动态查询(2)——关键字查询
- T-SQL动态查询(2)——关键字查询
- ios 图片拼接 图片缩放 将webView上面的内容转化为图片 归纳整理
- Selector uniquing in the dyld shared cache
- javascript闭包(Closure)初探
- hdu 1233 最小生成树
- Eclipse中定制快捷键