中后序遍历建树求前序
【问题描述】
给定二叉树节点个数以及其中序遍历和后序遍历,求其前序遍历。
【输入形式】
共三行。
第一行是一个正整数N,表示节点个数。
第二行共N个正整数,表示二叉树的中序遍历。
第三行共N个正整数,表示二叉树的后序遍历。
【输出形式】
共一行,输出前序遍历。
【样例输入】
10
3 6 7 4 5 9 10 2 8 1
3 7 6 5 10 9 4 8 1 2
【样例输出】
2 4 6 3 7 9 5 10 1 8
【数据范围】
N <= 10000
#include<iostream>
using namespace std;
template <class T>
class seqQueue {
friend int main();
private:
T*elem;
int maxSize;
int front, rear;
void doubleSpace();
public:
seqQueue(int size = 10);
~seqQueue();
bool isEmpty()const;
void enQueue(const T&x);
T deQueue();
T getHead()const;
};
template<class T>
seqQueue<T>::seqQueue(int size)
{
elem = new T[size];
maxSize = size;
front = rear = 0;
}
template<class T>
seqQueue<T>::~seqQueue()
{
delete[]elem;
}
template<class T>
bool seqQueue<T>::isEmpty()const
{
return (front == rear);
}
template<class T>
T seqQueue<T>::deQueue()
{
front = (front + 1) % maxSize;
return elem[front];
}
template<class T>
T seqQueue<T>::getHead()const
{
return elem[(front + 1) % maxSize];
}
template<class T>
void seqQueue<T>::enQueue(const T&x)
{
if ((rear + 1) % maxSize == front)
{
doubleSpace();
}
rear = (rear + 1) % maxSize;
elem[rear] = x;
}
template<class T>
void seqQueue<T>::doubleSpace()
{
T*tmp = elem;
elem = new T[2 * maxSize];
for (int i = 1; i <= maxSize - 1; i++)
{
elem[i] = tmp[(front + i) % maxSize];
}
front = 0;
rear = maxSize - 1;
maxSize *= 2;
delete[]tmp;
}
#pragma once
#include<iostream>
template <class T>
class linkQueue
{
private:
struct node {
T data;
node*next;
node() :next(NULL) {}
node(const T&x, node*N = NULL)
{
data = x;
next = N;
}
~node() {}
};
node*front, *rear;
public:
linkQueue();
~linkQueue();
bool isEmpty()const;
void enQueue(const T &x);
T deQueue();
T getHead()const;
};
template <class T>
linkQueue<T>::linkQueue() {
front = rear = NULL;
}
template <class T>
linkQueue<T>::~linkQueue() {
node*tmp;
while (front != NULL)
{
tmp = front;
front = front->next;
delete tmp;
}
}
template <class T>
bool linkQueue<T>::isEmpty()const {
return (front == NULL);
}
template <class T>
void linkQueue<T>::enQueue(const T&x)
{
if (rear == NULL) { front = rear = new node(x); }
else
{
rear->next = new node(x);
rear = rear->next;
}
}
template <class T>
T linkQueue<T>::getHead()const {
return front->data;
}
template <class T>
T linkQueue<T>::deQueue() {
node*tmp = front;
T x = tmp->data;
front = front->next;
if (front == NULL) { rear = NULL; }//注意一个量变化对其他量的可能影响
delete tmp;
return x;
}
using namespace std;
//binaryTree的前向说明
template <class T>
class binaryTree;
template <class T>
class node
{
friend class binaryTree<T>;
private:
node *left, *right;//结点左右子结点地址
T data;
public:
node() { left = NULL; right = NULL; };
node(T x, node*l = NULL, node*r = NULL) { data = x; left = l; right = r; };
~node() {}
};
template <class T>
class binaryTree
{
private:
node<T>*root;
T stopFlag;
int Size(node<T>*t);//求以t为根结点二叉树的结点个数
int Height(node<T>*t);//求以t为根结点二叉树的高度
void DelTree(node<T>*t);//删除以t为根结点的二叉树
void PreOrder(node<T>*t);//前序遍历输出
void InOrder(node<T>*t);//中序遍历输出
void PostOrder(node<T>*t);//后序遍历输出
void LevelOrder(node<T>*t);//层次遍历输出
public:
node<T>*buildTree_post(T post[], int pl, int pr, T mid[], int ml, int mr);//中序后序建树
binaryTree() { root = NULL; }//构造空二叉树
void createTree(const T&falg);
bool isEmpty() { return (root == NULL); }
node<T>*GetRoot() { return root; }
int Size();//求以t为根结点二叉树的结点个数
int Height();//求以t为根结点二叉树的高度
void DelTree();//删除以t为根结点的二叉树
void PreOrder();//前序遍历输出
void InOrder();//中序遍历输出
void PostOrder();//后序遍历输出
void LevelOrder();//层次遍历输出
};
template<class T>
void binaryTree<T>::createTree(const T&wuzi)//创建二叉树
{
bool flag;
seqQueue<node<T>*>que;
T e, el, er;
node<T>*p, *pl, *pr;
stopFlag = wuzi;
flag = wuzi;
cout << "Please input the root:"; cin >> e;//先判断根有无子
if (e == flag) { root = NULL; return; }//wuzi为无子标志
p = new node<T>(e);
root = p;//根进队列 输入并判断子
que.enQueue(e);
while (!que.isEmpty())//队列与树的对应实现
{
p = que.front();
que.deQueue();//获得队首元素并出队 同时进子结点
cout << "Please input the left child and the right child of" << p->data << "using " << flag <<
"as no child:";
cin >> el >> er;//输入子元素后不为flag为其申请空间
if (el != flag)//该结点有左孩子
{
pl = new node<T>(el);
p->left = pl;//没问题就把父子关系定下来
que.enQueue(pl);//左子进队列
}
if (er != flag)//该结点有右孩子
{
pr = new node<T>(er);
p->right = pr;//没问题就把父子关系定下来
que.enQueue(pr);//右子进队列
}
}
}
template<class T>
node<T>*binaryTree<T>::buildTree_post(T post[], int pl, int pr, T mid[], int ml, int mr)
{
//post数组储存了后序遍历序列,pl pr为序列左右边界下标
//mid数组储存了中序遍历序列,ml mr为序列左右边界下标
node<T>*p, *leftRoot, *rightRoot;
int i, pos, num;
int lpl, lpr, lml, lmr;//左子树后中序的左右边界
int rpl, rpr, rml, rmr;//右子树后中序的左右边界
if (pl > pr)return NULL;
p = new node<T>(post[pr]);//找到子树的根并创建结点
if (!root)root = p;
for (i = ml; i <= mr; i++)//找根在中序中的位置和左子树中结点个数
{
if (mid[i] == post[pr])break;
}
pos = i;//子树根在中序中的下标
num = pos - ml;//子树根的左子树中结点的个数
lpl = pl; lpr = pl + num - 1;//找左子树的前中序序列下标范围
lml = ml; lmr = pos - 1;
leftRoot = buildTree_post(post, lpl, lpr, mid, lml, lmr);
rpl = pl + num; rpr = pr - 1;
rml = pos + 1; rmr = mr;
rightRoot = buildTree_post(post, rpl, rpr, mid, rml, rmr);
p->left = leftRoot;
p->right = rightRoot;
return p;
}
template <class T>
void binaryTree<T>::PreOrder()
{
PreOrder(root);
}
template <class T>
void binaryTree<T>::PreOrder(node<T>*t)//前序遍历以t为根二叉树递归算法的实现
{
if (!t) { return; }//对空的检验
cout << t->data << " ";//根左右
PreOrder(t->left);
PreOrder(t->right);
}
template <class T>
void binaryTree<T>::InOrder()
{
InOrder(root);
}
template <class T>
void binaryTree<T>::InOrder(node<T>*t)//中序遍历以t为根二叉树递归算法的实现
{
if (!t) { return; }//对空的检验
InOrder(t->left);//左根右
cout << t->data;
InOrder(t->right);
}
template <class T>
void binaryTree<T>::PostOrder()
{
PostOrder(root);
}
template <class T>
void binaryTree<T>::PostOrder(node<T>*t)//中序遍历以t为根二叉树递归算法的实现
{
if (!t) { return; }//对空的检验
PostOrder(t->left);//左右根
cout << t->data;
PostOrder(t->right);
}
template <class T>
void binaryTree<T>::LevelOrder()
{
LevelOrder(root);
}
template <class T>
void binaryTree<T>::LevelOrder(node<T>*t)
{
linkQueue<node<T>*>que;
node<T>*tmp;
que.enQueue(root);
while (!que.isEmpty())
{
tmp = que.deQueue();
if (tmp->left)que.enQueue(tmp->left);
if (tmp->right)que.enQueue(tmp->right);
}
}
template<class T>
int binaryTree<T>::Size()//递归求规模
{
return Size(root);
}
template<class T>
int binaryTree<T>::Size(node<T>*t)
{
if (!t)return 0;
return 1 + Size(t->left) + Size(t->right);
}
template<class T>
int binaryTree<T>::Height()//递归求高度
{
return Height(root);
}
template<class T>
int binaryTree<T>::Height(node<T>*t)
{
int hl, hr;
if (!t)return 0;
hl = Height(t->left);
hr = Height(t->right);
if (hl >= hr)return hl + 1;
return hr + 1;
}
template<class T>
void binaryTree<T>::DelTree()
{
DelTree(root);
root = NULL;
}
template<class T>
void binaryTree<T>::DelTree(node<T>*t)//递归删除
{
if (!t)return;
DelTree(t->left);
DelTree(t->right);
delete t;
}
int main()
{
int n, i;
cin >> n;
int*a = new int[n];
int*b = new int[n];
binaryTree<int>x;
for (i = 0; i <= n - 1; i++)
{
cin >> a[i];
}
for (i = 0; i <= n - 1; i++)
{
cin >> b[i];
}
x.buildTree_post(b, 0, n - 1, a, 0, n - 1);
x.PreOrder();
system("pause");
delete[]a;
delete[]b;
}