一、概述
根据输入建一棵二叉排序树,对其进行先序遍历和镜像先序遍历。然后后序遍历并输出。
这题通过率很高,但我觉得很麻烦——通过率很高大概是因为能把样例过了就全过了的缘故。
二、分析
首先要建一棵二叉排序树,如下:
scanf("%d",&N);
int i;
root->lchild=NULL;
root->rchild=NULL;
int b;
scanf("%d",&b);
root->data=b;
start.push_back(b);
for(i=0;i<N-1;i++)
{
int a;
scanf("%d",&a);
start.push_back(a);
insert(root,a);
}
insert函数如下:
void insert(node* root,int a)
{
if(root->data>a)
if(root->lchild!=NULL)
insert(root->lchild,a);
else
{
node* leaf=new node;
leaf->data=a;
leaf->lchild=NULL;
leaf->rchild=NULL;
root->lchild=leaf;
return;
}
else
if(root->rchild!=NULL)
insert(root->rchild,a);
else
{
node* leaf=new node;
leaf->data=a;
leaf->lchild=NULL;
leaf->rchild=NULL;
root->rchild=leaf;
return;
}
}
二叉排序树有按序插入的性质,小于插左边大于插右边。什么时候插呢?root=NULL的时候插就可以了。在插之前要先建一个node并声明空间,然后初始化,不要忘了指针置为NULL,然后接上去即可。
另外要注意一点,很多insert函数的参数都是node*&root,而我的是node* root。例如下面的insert:
void insert(node* &root,int x)
{
if(root==NULL)
{
root=newNode(x);
return;
}
if(条件一)
{
insert(root->lchild,x);
}
else
{
insert(root->lchild,x);
}
}
注意观察二者的区别,下面的插入函数是直接在root上开了一个node大小的空间,而我是首先声明一个根节点,创建好后在根节点上操作,再声明一个node空间,接到根节点上。本质上我并没有修改根节点自己。因此我不需要用取地址操作。
当然,无论是出于简洁的角度还是不需准备的角度,人家都比我写得好。
然后是前序遍历以及镜像前序遍历。
前序遍历是十分好写的,如下
void preorder(node* root)
{
if(root->data!=NULL)
pre.push_back(root->data);
if(root->lchild!=NULL)
preorder(root->lchild);
if(root->rchild!=NULL)
preorder(root->rchild);
}
因为懒得数了,所以直接用vector来push一下很简单。镜像前序遍历的区别就是:镜像遍历是先右后左的,明白了这点就不用再去建一棵镜像树了,又麻烦又容易晕。如下:
void preordermirror(node* root)
{
if(root->data!=NULL)
mirror.push_back(root->data);
if(root->rchild!=NULL)
preordermirror(root->rchild);
if(root->lchild!=NULL)
preordermirror(root->lchild);
}
也是用vector来实现。写多了以后就越来越喜欢全局变量。
遍历之后就要判断初始序列是和哪个相等了。
注意!两个向量a和b中所有元素都相等,判断这个可以直接用a==b,即
if(start==pre)
{
equal_pre=1;
}
if(start==mirror)
{
equal_mirror=1;
}
而不用像我这样麻烦的
for(it_pre=pre.begin(),it_start=start.begin();it_pre!=pre.end(),it_start!=start.end();it_pre++,it_start++)
if(*it_pre!=*it_start)
{
equal_pre=0;
break;
}
for(it_mirror=mirror.begin(),it_start=start.begin();it_mirror!=mirror.end(),it_start!=start.end();it_mirror++,it_start++)
if(*it_mirror!=*it_start)
{
equal_mirror=0;
break;
}
这个很方便。
之后选择对应的输出即可,后序遍历和镜像后序遍历也类似,就不赘述了。
三、总结
本题应用了建树、树的遍历、排序树的性质等知识点,不难,但需要熟练。
PS:代码如下
#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
struct node
{
int data;
node* lchild;
node* rchild;
};
node* root=new node;
vector<int> pre;
vector<int> mirror;
vector<int> start;
int postnum=0;
int N;
void insert(node* root,int a)
{
if(root->data>a)
if(root->lchild!=NULL)
insert(root->lchild,a);
else
{
node* leaf=new node;
leaf->data=a;
leaf->lchild=NULL;
leaf->rchild=NULL;
root->lchild=leaf;
return;
}
else
if(root->rchild!=NULL)
insert(root->rchild,a);
else
{
node* leaf=new node;
leaf->data=a;
leaf->lchild=NULL;
leaf->rchild=NULL;
root->rchild=leaf;
return;
}
}
void preorder(node* root)
{
if(root->data!=NULL)
pre.push_back(root->data);
if(root->lchild!=NULL)
preorder(root->lchild);
if(root->rchild!=NULL)
preorder(root->rchild);
}
void postorder(node* root)
{
if(root->lchild!=NULL)
postorder(root->lchild);
if(root->rchild!=NULL)
postorder(root->rchild);
if(root->data!=NULL)
{
printf("%d",root->data);
postnum++;
if(postnum<N)
printf(" ");
}
}
void postordermirror(node* root)
{
if(root->rchild!=NULL)
postordermirror(root->rchild);
if(root->lchild!=NULL)
postordermirror(root->lchild);
if(root->data!=NULL)
{
printf("%d",root->data);
postnum++;
if(postnum<N)
printf(" ");
}
}
void preordermirror(node* root)
{
if(root->data!=NULL)
mirror.push_back(root->data);
if(root->rchild!=NULL)
preordermirror(root->rchild);
if(root->lchild!=NULL)
preordermirror(root->lchild);
}
int main()
{
scanf("%d",&N);
int i;
root->lchild=NULL;
root->rchild=NULL;
int b;
scanf("%d",&b);
root->data=b;
start.push_back(b);
for(i=0;i<N-1;i++)
{
int a;
scanf("%d",&a);
start.push_back(a);
insert(root,a);
}
preorder(root);
preordermirror(root);
vector<int>::iterator it_pre;
vector<int>::iterator it_mirror;
vector<int>::iterator it_start;
int equal_pre=1;
int equal_mirror=1;
////////////////////////////////////////
/*printf("pre:\n");
for(it_pre=pre.begin();it_pre!=pre.end();it_pre++)
printf("%d ",*it_pre);
printf("\nmirror:\n");
for(it_mirror=mirror.begin();it_mirror!=mirror.end();it_mirror++)
printf("%d ",*it_mirror);
printf("\nstart:\n");
for(it_start=start.begin();it_start!=start.end();it_start++)
printf("%d ",*it_start);*/
////////////////////////////////////////
for(it_pre=pre.begin(),it_start=start.begin();it_pre!=pre.end(),it_start!=start.end();it_pre++,it_start++)
if(*it_pre!=*it_start)
{
equal_pre=0;
break;
}
for(it_mirror=mirror.begin(),it_start=start.begin();it_mirror!=mirror.end(),it_start!=start.end();it_mirror++,it_start++)
if(*it_mirror!=*it_start)
{
equal_mirror=0;
break;
}
if(equal_pre==1)
{
printf("YES\n");
postorder(root);
}
else if(equal_mirror==1)
{
printf("YES\n");
postordermirror(root);
}
else
printf("NO");
}