最近机考,复习一下。之前做这道题时候没有用递归,今天用递归写了一下。
前序:4,3,1,2,5,6,7
中序: 1,3,2,4,6,5,7
后序: 1,2,3,6,7,5,4
思想很简单,就是前序的第一个一定是根,在中序的输出中,这个点左侧的都是左子树,右边的都是右子树。然后再递归的分别找左右子树的根。
代码如下:
#include <iostream>
using namespace std;
int Left[100001]={0},Right[100001]={0},weight[100001]={0};
int root;
int find_root(int pre[],int mid[],int length)
{
int index=0;
if(length==0)
return 0;//叶用0来表示
for(;index<length;++index)
{
if(mid[index]==pre[0])
break;
}
Right[mid[index]]=find_root(pre+index+1,mid+index+1,length-index-1);
Left[mid[index]]=find_root(pre+1,mid,index);
return mid[index];
}
void postOrder(int root)
{
if(Left[root]!=0)
postOrder(Left[root]);
if(Right[root]!=0)
postOrder(Right[root]);
cout<<root;
}
int main()
{
int pre[]={4,3,1,2,5,6,7};
int mid[]={1,3,2,4,6,5,7};
root = find_root(pre,mid,7);
postOrder(root);
return 0;
}
之前写了个非递归的很长的代码,不适合机考。【话说你们这帮人机考一个类都不写真的好么==】
非递归的核心代码:
void BinaryTree::creatTree()
{
ifstream fin("chenrenwangaijiexi.txt");
char A[100],B[100];
int i(0);int j(0);
char ch = fin.get();
while(ch!='\n')
{
if(ch!=' ')
A[i++]=ch;
ch = fin.get();
}
A[i]='\0';
while(fin>>ch)
{
B[j++]=ch;
}
B[j]='\0';
int len_a = strlen(A);
root = new Node(A[0]);
for(i=1;i<len_a;++i)
{
ch = A[i];
Node* curr = root;
while(1)
{
if(isLeft(B,ch,curr->data)){
if(curr->left==NULL){curr->left=new Node(ch);break;}
else {curr=curr->left;continue;}
}
else{
if(curr->right==NULL)
{curr->right=new Node(ch);break;}
else{curr = curr->right;continue;}
}
}
}
}
里面的isLeft是用于判断在中序遍历B中的相对位置,进而判断在做子树或者右子树上面。
inline bool isLeft(char a[],int ch1,int ch2)
{
return strchr(a,ch1)<strchr(a,ch2);
}
strchr是<cstring>里面的一个判断位置的函数。
非递归的函数比较难以理解,就是先找到跟,然后不断地去判断pre输出里面的每一个节点的值再中序遍历中是在这个点的左边还是右边,如果是在根的左边,就和跟的左边比较,在右边就和右边的比较,直到左或者有子树为空,这样就可以插入这个节点的值了。不断地插入,直到所有的节点值都插入就结束了。