重构二叉树
-
引言
好久没写代码了,手有点生了。。。博客如有不好之处,还请指出,谢谢大家一直对我的关注。相信自己,相信未来。有句话说得好,不怕贼偷就怕贼惦记,举一反三,人生中的种种问题也是如此,不怕我们解决,就怕我们一直惦记着它。愿我们各种前进,各种加油。
-
题目
知道二叉树中序遍历和先序遍历的结果,然后重构二叉树。
-
思路
本人思路是如果不写程序,把此题当问答题,本人是可以解答的,但是如果写程序怎么办呢?
本人思路有两步:
1)根据中序遍历,对二叉树中的关键字建立哈希表,目的就是通过关键字可以得到其在中序遍历中的位置;空间复杂度O(n),时间复杂度也是O(n);前提是二叉树中的关键字是不重复的;
2)利用第一步的结果,把关键字在中序遍历中的位置作为关键字的value值,新建一个二叉树,新建的过程是把先序遍历中的每个关键字从前往后依次插入,时间复杂度为O(n*log n);
说个例子吧,还好理解些,如下
重建二叉树后,如下
-
实验
程序截图如下
-
代码
binary_tree.h
#include <iostream> #include <utility> #include <string> #include <cmath> using namespace std; template<typename T> class btnode { public: T key; btnode * Lchild; btnode * Rchild; // function:make function btnode( ); }; template<typename T> btnode<T>::btnode() { key = -1; Lchild = NULL; Rchild = NULL; }; template<typename T> class tree { private: // function:insert data to node from string to tree void tree<T>::_data_into_node(T data,btnode<T>* &Tree,int *hash,int hash_length); public: // var:R id the root of the tree btnode<T> * R; // function:make function tree(); // function:make tree void _maketree(T * data,size_t s); // function:insert key into tree void tree<T>::_insert(btnode<T> * *bt,T d); // function:visit node p void _visit(btnode<T> * p); // fucntion:preorder visit tree void _preOrderTraver(btnode<T> * p); // fucntion:inorder visit tree void _inOrderTraver(btnode<T> * p); // fucntion:postorder visit tree void tree<T>::_postOrderTraver(btnode<T> * p); // function:whether is balanced binary tree std::pair<size_t,bool> _IsBalancedBinaryTree(btnode<T> *p); // function: string to tree btnode<T> * tree<T>::_data_to_tree(T * _preorder,int plength,T * _inorder,int ilength); }; // function:make function template<typename T> tree<T>::tree() { this->R = NULL; }; // function:make tree // input:an array of data and its length // output: a binary tree template<typename T> void tree<T>::_maketree(T * data,size_t s) { for(size_t i= 0;i<s;i++) { this->_insert(&(this->R),data[i]); } }; // function:insert key into tree template<typename T> void tree<T>::_insert(btnode<T> * *bt,T d) { if((*bt) == NULL) { (*bt) = new btnode<T>; (*bt) -> key = d; } else { btnode<T> * p = *bt ; if(d < p->key) { this->_insert(&(p->Lchild),d); } else if(d>p->key) { this->_insert(&(p->Rchild),d); } else { cout<<d<<" has been inserted"<<endl; } } }; // function:visit node p template<typename T> void tree<T>::_visit(btnode<T> * p) { if(p != NULL) { cout<<"key="<<p->key<<endl; } else { cout<<"node point null"<<endl; } }; // fucntion:preorder visit tree template<typename T> void tree<T>::_preOrderTraver(btnode<T> * p) { if(p != NULL ) { this->_visit(p); this->_preOrderTraver(p->Lchild); this->_preOrderTraver(p->Rchild); } }; // fucntion:inorder visit tree template<typename T> void tree<T>::_inOrderTraver(btnode<T> * p) { if(p != NULL ) { this->_inOrderTraver(p->Lchild); this->_visit(p); this->_inOrderTraver(p->Rchild); } }; // fucntion:postorder visit tree template<typename T> void tree<T>::_postOrderTraver(btnode<T> * p) { if(p != NULL ) { this->_postOrderTraver(p->Lchild); this->_postOrderTraver(p->Rchild); this->_visit(p); } }; // function:whether is balanced binary tree template<typename T> std::pair<size_t,bool> tree<T>::_IsBalancedBinaryTree(btnode<T> *p) { if( p == NULL ) return std::make_pair(0,true); else { std::pair<size_t,bool> r = this -> _IsBalancedBinaryTree(p->Rchild); std::pair<size_t,bool> l = this -> _IsBalancedBinaryTree(p->Lchild); int h = (int)(r.first) - (int)(l.first); h = abs(h); if(h>1) return std::make_pair(max(r.first,l.first)+1,false); else return std::make_pair(max(r.first,l.first)+1,r.second && l.second); } }; // function: string to tree template<typename T> btnode<T> * tree<T>::_data_to_tree(T * _preorder,int plength,T * _inorder,int ilength) { if( plength > 0 && ilength > 0 ) { btnode<T> * p = NULL; int * hash = new int[ilength]; T zero = 0; for(int i=0;i<ilength;i++) { hash[ abs(_inorder[i] - zero) % ilength ] = i; } for(int i=0;i<plength;i++) { //function:insert data into tree _data_into_node(_preorder[i],p,hash,ilength); } cout<<"inorder"<<endl; this->_inOrderTraver(p); cout<<"preprder"<<endl; this->_preOrderTraver(p); return p; } else { cout<<"exception of function :<string to tree> input"<<endl; } }; // function:insert data to node from string to tree template<typename T> void tree<T>::_data_into_node(T data,btnode<T>* &Tree,int *hash,int hash_length) { // insure all data is right if( hash != NULL || hash_length <= 0 ) { if( Tree == NULL ) { Tree = new btnode<T>() ; Tree -> key = data ; } else { T zero =0; btnode<T> * p =Tree; while(p != NULL) { if(hash[abs(data-zero)%hash_length] < hash[abs(p->key - zero)%hash_length]) { if(p->Lchild == NULL) { p->Lchild = new btnode<T>(); (p->Lchild)->key = data; break; } else p = p->Lchild; } else { if(p->Rchild == NULL) { p->Rchild = new btnode<T>(); (p->Rchild)->key =data; break; } else { p = p->Rchild; } } } } } else { cout<<"exception of function <_data_into_node> input"<<endl; } };
test.cpp
#include<iostream> #include "binary_tree.h" using namespace std; // function: main int main(){ tree<char> * T = new tree<char>(); char* P = "abdcef"; char* I = "dbaecf"; T->_data_to_tree(P,6,I,6); system("pause"); return 0; }