//二叉树的定义
typedef struct _BinaryTreeNode
{
char data;
//int ltag , rtag;
struct _BinaryTreeNode *lchild;
struct _BinaryTreeNode *rchild;
}BTNode;
/*
1、表达式(a-(b+c)*(d/e))存储在存储在以二叉链表为存储结构的二叉树中,编写程序求出表达式中的值。
*/
int op(int A,int B ,char oper)
{
switch (oper)
{
case '+':
return A+B;
break;
case '-':
return A-B;
break;
case '*':
return A*B;
break;
case '/':
return A/B;
break;
}
}
int comp(BTNode *p)
{
int A,B;
if (p!=NULL)
{
if (p->lchild!=NULL&&p->rchild!=NULL)
{
A = comp(p->lchild);
B = comp(p->rchild);
return op(A,B,p->data);
}
else
return p->data -'0';
}
else
return 0;
}
//写出一个算法求出二叉树的高度
int getDepth(BTNode *p)
{
int LD=0,RD=0;
if (p ==NULL)
{
return 0;
}
else
{
LD = getDepth(p->lchild);
RD = getDepth(p->rchild);
return (LD>RD ? LD:RD)+1;
}
}
//在以二叉链表为存储结构的链表中查询data域值等于key的节点。
//前序遍历就OK 可以用中序遍历么
void Search_one(BTNode *p, BTNode *&q, char key)
{
if (p!=NULL)
{
if (p->data==key)
{
q = p;
}
else
{
Search_one(p->lchild,q,key);
Search_one(p->rchild,q,key);
}
}
}
//前序遍历就OK 可以用中序遍历么
void Search_two(BTNode *p, BTNode *&q, char key)
{
if (p!=NULL)
{
if (p->data==key)
{
q = p;
}
else
{
Search_two(p->lchild,q,key);
if (q==NULL)
{
Search_two(p->rchild,q,key);
}//只有在左子树中没有找到才在右子树中找
}
}
}
//求出二叉树的最大宽度:某一层节点个数最多的那一层
int BinaryTreeWidth(BTNode *root)
{
//核心思想: 第一次入队根节点,这个时候的宽度为1 当根节点出队,其子节点入队之后,这个队列的大小就是这一层的宽度 以此类推。
if (root ==NULL)
{
return 0;
}
int width = 0;
int maxwidth =0;
queue<BTNode*> q;
BTNode *p = NULL;
q.push(root);
while(!q.empty())
{
width = q.size();//本层元素的个数
if (maxwidth<width)
{
maxwidth = width;
}
//将该层元素的孩子入栈
for (int i = 0;i<width;i++)
{
p = q.front();
q.pop();
if (p->lchild!=NULL)
{
q.push(p->lchild);
}
if (p->lchild!=NULL)
{
q.push(p->rchild);
}
}
}
return maxwidth;
//求二叉树的深度的非递归算法
/*
其实知道了树的深度的非递归算法,很容易知道树的深度 因为树的宽度的外层循环每进行一次,树的深度就增加1
*/
int BinaryTreeDepth(BTNode *root)
{
//核心思想: 第一次入队根节点,这个时候的宽度为1 当根节点出队,其子节点入队之后,这个队列的大小就是这一层的宽度 以此类推。
if (root ==NULL)
{
return 0;
}
int width = 0 ;
int dept = 0 ;
queue<BTNode*> q;
BTNode *p = NULL;
q.push(root);
while(!q.empty())
{
width = q.size();//本层元素的个数
dept++;
//将该层元素的孩子入栈
for (int i = 0;i<width;i++)
{
p = q.front();
q.pop();
if (p->lchild!=NULL)
{
q.push(p->lchild);
}
if (p->lchild!=NULL)
{
q.push(p->rchild);
}
}
}
return dept;
}
//中序和后续确定一颗树 --后续确定根的位置,中序把树分为两个部分
BTNode *BTConstruct23(char *inorder,char *postorder,int inStart,int inEnd,int postStart,int postEnd)
{
//建立新的节点
BTNode *tree = new BTNode;
tree->data =postorder[postEnd];//后序遍历的最后一个节点一定是根节点
tree->lchild =NULL;//前序遍历的第一个节点将中序遍历的节点分为左右子树
tree->rchild =NULL;
if (inStart==inEnd&&postStart==postEnd)
{
return tree;
}
int root =0;
//在中序遍历中查找该值
for ( root = inStart;root<inEnd;root++)
{
if (inorder[root]==postorder[postEnd])
break;
}
//划分左子树
int leftTreeLength = root - inStart;
//cout<<leftTreeLength<<endl;
int rightTreeLength = inEnd - root;
//cout<<rightTreeLength<<endl;
if (leftTreeLength>0)
{
//注意中序和后续保持元素个数相等即为正确的 leftTreeLength-1
tree->lchild = BTConstruct23(inorder,postorder,inStart,root-1,postStart,postStart+leftTreeLength-1);
}
if (rightTreeLength>0)
{
tree->rchild = BTConstruct23(inorder,postorder,root+1,inEnd,postStart+leftTreeLength,postEnd-1);
}
return tree;
}
BTNode *BTConstruct12(char *preorder,char *inorder,int preStart,int preEnd,int inStart,int inEnd)
{
//建立新的节点
BTNode *tree = new BTNode;
tree->data =preorder[preStart];//前序遍历的第一个节点一定是根节点
tree->lchild =NULL;//前序遍历的第一个节点将中序遍历的节点分为左右子树
tree->rchild =NULL;
if (preStart==preEnd&&inStart==inEnd)
{
return tree;
}
int root =0;
//在中序遍历中查找该值
for ( root = inStart;root<=inEnd;root++)
{
if (inorder[root]==preorder[preStart])
break;
}
//划分左子树
int leftTreeLength = root - inStart;
int rightTreeLength = inEnd - root;
if (leftTreeLength>0)
{
tree->lchild = BTConstruct12(preorder,inorder,preStart+1,preStart+leftTreeLength,inStart,root-1);
}
if (rightTreeLength>0)
{
tree->rchild = BTConstruct12(preorder,inorder,preStart+1+leftTreeLength,preEnd,root+1,inEnd);
}
return tree;
}
//根据二叉树的前序和中序遍历确定一颗二叉树
BTNode * RecoveryBinaryTreeBy12(char* preorder ,int lenpre,char *inorder,int lenin)
{
if (lenpre==0&& lenin==0)
{
return NULL;
}
return BTConstruct12(preorder,inorder,0,lenpre-1,0,lenin-1);
}
//去取出先序遍历的第k的点
int n =0;
void pretrave(BTNode*p ,int key)
{
if (p!=NULL)
{
n++;
if (key==n)
{
cout<<p->data<<endl;
return;
}
pretrave(p->lchild,key);
pretrave(p->rchild,key);
}
//cout<<"不存在"<<endl;
}
#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
#include<map>
#include<stack>
#include <queue>
#define MAX_Size 100;
using namespace std;
//
// BinaryTreeNode.h
// BinaryTreeNode
//
// Created by 吴珝君 on 2018/12/25.
// Copyright © 2018年 闲着也是贤者. All rights reserved.
//
typedef struct _BinaryTreeNode
{
char data;
//int ltag , rtag;
struct _BinaryTreeNode *lchild;
struct _BinaryTreeNode *rchild;
}BTNode;
/*
1、表达式(a-(b+c)*(d/e))存储在存储在以二叉链表为存储结构的二叉树中,编写程序求出表达式中的值。
*/
int op(int A,int B ,char oper)
{
switch (oper)
{
case '+':
return A+B;
break;
case '-':
return A-B;
break;
case '*':
return A*B;
break;
case '/':
return A/B;
break;
}
}
int comp(BTNode *p)
{
int A,B;
if (p!=NULL)
{
if (p->lchild!=NULL&&p->rchild!=NULL)
{
A = comp(p->lchild);
B = comp(p->rchild);
return op(A,B,p->data);
}
else
return p->data -'0';
}
else
return 0;
}
//写出一个算法求出二叉树的高度
int getDepth(BTNode *p)
{
int LD=0,RD=0;
if (p ==NULL)
{
return 0;
}
else
{
LD = getDepth(p->lchild);
RD = getDepth(p->rchild);
return (LD>RD ? LD:RD)+1;
}
}
//在以二叉链表为存储结构的链表中查询data域值等于key的节点。
//前序遍历就OK 可以用中序遍历么
void Search_one(BTNode *p, BTNode *&q, char key)
{
if (p!=NULL)
{
if (p->data==key)
{
q = p;
}
else
{
Search_one(p->lchild,q,key);
Search_one(p->rchild,q,key);
}
}
}
//前序遍历就OK 可以用中序遍历么
void Search_two(BTNode *p, BTNode *&q, char key)
{
if (p!=NULL)
{
if (p->data==key)
{
q = p;
}
else
{
Search_two(p->lchild,q,key);
if (q==NULL)
{
Search_two(p->rchild,q,key);
}//只有在左子树中没有找到才在右子树中找
}
}
}
//求出二叉树的最大宽度:某一层节点个数最多的那一层
int BinaryTreeWidth(BTNode *root)
{
//核心思想: 第一次入队根节点,这个时候的宽度为1 当根节点出队,其子节点入队之后,这个队列的大小就是这一层的宽度 以此类推。
if (root ==NULL)
{
return 0;
}
int width = 0;
int maxwidth =0;
queue<BTNode*> q;
BTNode *p = NULL;
q.push(root);
while(!q.empty())
{
width = q.size();//本层元素的个数
if (maxwidth<width)
{
maxwidth = width;
}
//将该层元素的孩子入栈
for (int i = 0;i<width;i++)
{
p = q.front();
q.pop();
if (p->lchild!=NULL)
{
q.push(p->lchild);
}
if (p->lchild!=NULL)
{
q.push(p->rchild);
}
}
}
return maxwidth;
}
//求二叉树的深度的非递归算法
/*
其实知道了树的深度的非递归算法,很容易知道树的深度 因为树的宽度的外层循环每进行一次,树的深度就增加1
*/
int BinaryTreeDepth(BTNode *root)
{
//核心思想: 第一次入队根节点,这个时候的宽度为1 当根节点出队,其子节点入队之后,这个队列的大小就是这一层的宽度 以此类推。
if (root ==NULL)
{
return 0;
}
int width = 0 ;
int dept = 0 ;
queue<BTNode*> q;
BTNode *p = NULL;
q.push(root);
while(!q.empty())
{
width = q.size();//本层元素的个数
dept++;
//将该层元素的孩子入栈
for (int i = 0;i<width;i++)
{
p = q.front();
q.pop();
if (p->lchild!=NULL)
{
q.push(p->lchild);
}
if (p->lchild!=NULL)
{
q.push(p->rchild);
}
}
}
return dept;
}
int m =0;
//中序和后续确定一颗树 --后续确定根的位置,中序把树分为两个部分
BTNode *BTConstruct23(char *inorder,char *postorder,int inStart,int inEnd,int postStart,int postEnd)
{
//建立新的节点
BTNode *tree = new BTNode;
tree->data =postorder[postEnd];//后序遍历的最后一个节点一定是根节点
tree->lchild =NULL;//前序遍历的第一个节点将中序遍历的节点分为左右子树
tree->rchild =NULL;
if (inStart==inEnd&&postStart==postEnd)
{
return tree;
}
int root =0;
//在中序遍历中查找该值
for ( root = inStart;root<inEnd;root++)
{
if (inorder[root]==postorder[postEnd])
break;
}
//划分左子树
int leftTreeLength = root - inStart;
//cout<<leftTreeLength<<endl;
int rightTreeLength = inEnd - root;
//cout<<rightTreeLength<<endl;
if (leftTreeLength>0)
{
//注意中序和后续保持元素个数相等即为正确的 leftTreeLength-1
tree->lchild = BTConstruct23(inorder,postorder,inStart,root-1,postStart,postStart+leftTreeLength-1);
}
if (rightTreeLength>0)
{
tree->rchild = BTConstruct23(inorder,postorder,root+1,inEnd,postStart+leftTreeLength,postEnd-1);
}
return tree;
}
//根据二叉树的前序和中序遍历确定一颗二叉树
BTNode * RecoveryBinaryTreeBy23(char* inorder ,int lenin,char *postorder,int lenpost)
{
if (lenin==0&& lenpost==0)
{
return NULL;
}
return BTConstruct23(inorder,postorder,0,lenin-1,0,lenpost-1);
}
void PostOrder(BTNode *root)
{
if (root ==NULL)
{
return ;
}
PostOrder(root->lchild);
PostOrder(root->rchild);
cout<<root->data<<endl;
}
BTNode *BTConstruct12(char *preorder,char *inorder,int preStart,int preEnd,int inStart,int inEnd)
{
//建立新的节点
BTNode *tree = new BTNode;
tree->data =preorder[preStart];//前序遍历的第一个节点一定是根节点
tree->lchild =NULL;//前序遍历的第一个节点将中序遍历的节点分为左右子树
tree->rchild =NULL;
if (preStart==preEnd&&inStart==inEnd)
{
return tree;
}
int root =0;
//在中序遍历中查找该值
for ( root = inStart;root<=inEnd;root++)
{
if (inorder[root]==preorder[preStart])
break;
}
//划分左子树
int leftTreeLength = root - inStart;
int rightTreeLength = inEnd - root;
if (leftTreeLength>0)
{
tree->lchild = BTConstruct12(preorder,inorder,preStart+1,preStart+leftTreeLength,inStart,root-1);
}
if (rightTreeLength>0)
{
tree->rchild = BTConstruct12(preorder,inorder,preStart+1+leftTreeLength,preEnd,root+1,inEnd);
}
return tree;
}
//根据二叉树的前序和中序遍历确定一颗二叉树
BTNode * RecoveryBinaryTreeBy12(char* preorder ,int lenpre,char *inorder,int lenin)
{
if (lenpre==0&& lenin==0)
{
return NULL;
}
return BTConstruct12(preorder,inorder,0,lenpre-1,0,lenin-1);
}
//去取出先序遍历的第k的点
int n =0;
void pretrave(BTNode*p ,int key)
{
if (p!=NULL)
{
n++;
if (key==n)
{
cout<<p->data<<endl;
return;
}
pretrave(p->lchild,key);
pretrave(p->rchild,key);
}
//cout<<"不存在"<<endl;
}
int main()
{
/*
测试程序
*/
//is2operator(v,vv,ms);
BTNode b1,b2,b3,b4,b5,b6,b7,b8,b9;
b1.data ='*';
b2.data ='-';
b3.data ='/';
b3.lchild =NULL;
b3.rchild =NULL;
b4.data ='a';
b4.lchild =NULL;
b4.rchild =NULL;
b5.data ='+';
b5.lchild =NULL;
b5.rchild =NULL;
b5.data ='+';
b5.lchild =NULL;
b5.rchild =NULL;
b6.data ='d';
b6.lchild =NULL;
b6.rchild =NULL;
b7.data ='e';
b7.lchild =NULL;
b7.rchild =NULL;
b8.data ='b';
b8.lchild =NULL;
b8.rchild =NULL;
b9.data ='c';
b9.lchild =NULL;
b9.rchild =NULL;
b1.lchild = &b2;
b1.rchild =&b3;
b2.lchild =&b4;
b2.rchild =&b5;
b3.lchild =&b6;
b3.rchild = &b7;
b5.lchild = &b8;
b5.rchild =&b9;
char preorder[9] ={'*','-','a','+','b','c','/','d','e'};
char inorder[9] ={'a','-','b','+','c','*','d','/','e'};
char postorder[9] ={'a','b','c','+','-','d','e','/','*'};
//BTNode * r1= RecoveryBinaryTreeBy12(preorder,9,inorder,9);
//PostOrder(r1);
BTNode * r2= RecoveryBinaryTreeBy23(inorder,9,postorder,9);
PostOrder(r2);
system("pause");
}