#ifndef CLEARN_BTREE_H
#define CLEARN_BTREE_H
#include<iostream>
#include<vector>
#include<string>
#include<list>
using namespace std;
//定义树的类型,采用二叉链式存储结构
typedef struct node{
char val;
node *left;
node *right;
} BTNode;
class BTree{
public:
//无参构造器
BTree(){
roots = nullptr;
size = 0;
}
//有参构造器
BTree (const string &data){
roots = nullptr;
size = 0;
roots = createBtree(data);
}
//拷贝构造函数
BTree(BTree &data){
this->roots = data.roots;
this->size = data.size;
}
//析构函数
~BTree(){
destoryTree(roots);
}
//采用前序遍历的方法来输出二叉树,采用递归的方法来输出二叉树
void midOdrder() {
midOrder(roots);
cout << endl;
}
void inOrder(){
inOrder(roots);
cout<<endl;
}
void lastOrder(){
lastOrder(roots);
cout<<endl;
}
//采用非递归的方式输出二叉树
//非递归的先序遍历
void midOrder_by_none_recursion(){
//采用栈
vector<BTNode*> stack;
BTNode *p = roots;
stack.push_back(p);
while(!stack.empty()){
p = stack.back();
stack.pop_back();
cout<<p->val<<" ";
if(p->right!= nullptr){
stack.push_back(p->right);
}
if(p->left!= nullptr){
stack.push_back(p->left);
}
}
cout<<endl;
}
//非递归的中序遍历
void inOrder_by_none_recursion(){
vector<BTNode*> stack;
BTNode *p = roots;
while(p!= nullptr||!stack.empty()){
while(p!= nullptr){
stack.push_back(p);
p = p->left;
}
if(!stack.empty()){
p = stack.back();
stack.pop_back();
cout<<p->val<<" ";
p = p->right;
}
}
cout<<endl;
}
//非递归的后序遍历
void lastOrder_by_none_recursion(){
BTNode *p,*r;
bool flag;
vector<BTNode*> stack;
p = roots;
do{
while (p!= nullptr){
stack.push_back(p);
p = p->left;
}
r = nullptr;
flag = true;
while(!stack.empty()&&flag){
p = stack.back();
if(p->right==r){
cout<<p->val<<" ";
stack.pop_back();
r = p;
}
else{
p = p->right;
flag = false;
}
}
}while(!stack.empty());
cout<<endl;
}
//单层的层次遍历
void levelOrder(){
list<BTNode*> queue;
BTNode *p = roots;
queue.push_back(p);
while(!queue.empty()){
p = queue.front();
queue.pop_front();
cout<<p->val<<" ";
if(p->left!= nullptr){
queue.push_back(p->left);
}
if(p->right!= nullptr){
queue.push_back(p->right);
}
}
cout<<endl;
}
//一层一层打印二叉树
void levelOrder_onebyone_layor(){
list<BTNode*> queue;
BTNode *p = roots;
queue.push_back(roots);
int len,i;
while(!queue.empty()){
len = queue.size();
i = 0;
while(i<len){
p = queue.front();
queue.pop_front();
cout<<p->val<<" ";
if(p->left!= nullptr)
queue.push_back(p->left);
if(p->right!= nullptr)
queue.push_back(p->right);
i++;
}
cout<<endl;
}
}
//根据二叉树的先序遍历和中序遍历重建二叉树
BTree(string midOrder,string inOrder,bool style = false){
int size = 0;
if(!style)
roots = createBtree_by_midOrder_and_inOrder(midOrder,inOrder,0,midOrder.size()-1,0,inOrder.size()-1,size);
else{
roots = createBtree_by_lastOrder_and_inOrder(midOrder,inOrder,0,midOrder.size()-1,0,inOrder.size()-1,size);
}
this->size = size;
}
//二叉树的基本运算,输出某个结点的左右孩子
void getChild(char data){
getChild(roots,data);
}
//输出二叉树的高度
int treeHeight(){
return treeHeight(roots);
}
//非递归的方式遍历二叉树
private:
BTNode *roots;
int size;
/**
* - 如果ch为'('说明其前一个字符是有孩子结点的,那么将此符号入栈,并且先从左节点开始添加,此时k=1
* - 当遇到')'说明结点添加结束,将栈顶元素出栈
* - 当遇到','将k置为2,说明是右节点的添加
* - 其他情况根据k的值添加元素
* @param data
* @return
*/
BTNode* createBtree(string data){
BTNode *roots = nullptr;
int k = 1,i=0;
BTNode *p;
vector<BTNode*> stack;
while(i<data.size()){
switch (data[i]) {
case'(': stack.push_back(p);k=1;break;
case ')': stack.pop_back();break;
case ',': k=2;break;
default:{
p = (BTNode*)malloc(sizeof(BTNode));
p->left = p->right = nullptr;
p->val = data[i];
if(roots == nullptr)
roots = p;
else{
if(k==1){
stack.back()->left = p;
}else if(k==2){
stack.back()->right = p;
}
}
size++;
}
}
i++;
}
return roots;
}
private:
//销毁一颗二叉树
void destoryTree(BTNode *&p){
if(p== nullptr)
return;
destoryTree(p->left);
destoryTree(p->right);
delete p; //释放指针指向的空间
p = nullptr; //防止出现空悬指针
}
private:
//递归的方法遍历二叉树,从上到下分别为先序遍历、中序遍历、后序遍历
void midOrder(BTNode *roots){
if(roots== nullptr)
return;
cout<<roots->val<<" ";
midOrder(roots->left);
midOrder(roots->right);
}
void inOrder(BTNode *roots){
if(roots== nullptr)
return;
inOrder(roots->left);
cout<<roots->val<<" ";
inOrder(roots->right);
}
void lastOrder(BTNode *roots){
if(roots==nullptr)
return;
lastOrder(roots->left);
lastOrder(roots->right);
cout<<roots->val<<" ";
}
//输出二叉树中结点的孩子结点
void getChild(BTNode* roots,char data){
if(roots== nullptr)
return;
if(roots->val == data){
if(roots->left!= nullptr){
cout<<roots->left->val<<" ";
}
if(roots->right!=nullptr){
cout<<roots->right->val<<" ";
}
cout<<endl;
return;
}
getChild(roots->left,data);
getChild(roots->right,data);
}
//输出二叉树中某个结点的双亲结点
private:
//求树的高度
int treeHeight(BTNode *roots){
if(roots== nullptr)
return 0;
return 1+ max(treeHeight(roots->left), treeHeight(roots->right));
}
private:
//根据中序遍历和先序遍历恢复一颗二叉树
BTNode* createBtree_by_midOrder_and_inOrder( string &preOrder,string &inOrder
,int pre_start,int pre_end,int in_start,int in_end,int &size){
BTNode *p = (BTNode*) malloc(sizeof(BTNode));
size++;
p->val = preOrder[pre_start];
p->left = nullptr;
p->right = nullptr;
int k = in_start;
for(;k<in_end;k++){
if(preOrder[pre_start]==inOrder[k])
break;
}
if(pre_start==pre_end)
return p;
else{
if(k==in_start){
p->right = createBtree_by_midOrder_and_inOrder(preOrder,inOrder,pre_start+1,pre_end,k+1,in_end,size);
}
else if(k==in_end){
p->left = createBtree_by_midOrder_and_inOrder(preOrder,inOrder,pre_start+1,pre_end,in_start,k-1,size);
}
else{
p->left = createBtree_by_midOrder_and_inOrder(preOrder,inOrder,pre_start+1,pre_start+k-in_start,in_start,k-1,size);
p->right = createBtree_by_midOrder_and_inOrder(preOrder,inOrder,pre_start+k-in_start+1,pre_end,k+1,in_end,size);
}
}
return p;
}
//根据中序遍历和后序遍历恢复一颗二叉树
BTNode* createBtree_by_lastOrder_and_inOrder(string &lastOrder,string &inOrder,int last_start,int last_end,int in_start,int in_end,int &size){
BTNode *p = (BTNode*)malloc(sizeof(BTNode));
p->val = lastOrder[last_end];
p->left = nullptr;
p->right = nullptr;
size++;
int k = in_start;
for(;k<in_end;k++){
if(inOrder[k]==lastOrder[last_end])
break;
}
if(last_end==last_start)
return p;
if(k==in_start){
p->right = createBtree_by_lastOrder_and_inOrder(lastOrder,inOrder,last_start,last_end-1,k+1,in_end,size);
}else if(k==in_end){
p->left = createBtree_by_lastOrder_and_inOrder(lastOrder,inOrder,last_start,last_end-1,in_start,k-1,size);
}else{
p->left = createBtree_by_lastOrder_and_inOrder(lastOrder,inOrder,last_start,last_start+k-in_start-1,in_start,k-1,size);
p->right = createBtree_by_lastOrder_and_inOrder(lastOrder,inOrder,last_start+k-in_start,last_end-1,k+1,in_end,size);
}
return p;
}
};
#endif //CLEARN_BTREE_H