Problem Description
在树结构中,有一种特殊的二叉树叫做排序二叉树,直观的理解就是——(1).每个节点中包含有一个关键值 (2).任意一个节点的左子树(如果存在的话)的关键值小于该节点的关键值 (3).任意一个节点的右子树(如果存在的话)的关键值大于该节点的关键值。现给定一组数据,请你对这组数据按给定顺序建立一棵排序二叉树,并输出其中序遍历的结果。
Input
输入包含多组数据,每组数据格式如下。
第一行包含一个整数n,为关键值的个数,关键值用整数表示。(n<=1000)
第二行包含n个整数,保证每个整数在int范围之内。
Output
为给定的数据建立排序二叉树,并输出其中序遍历结果,每个输出占一行。
Example Input
1
2
2
1 20
Example Output
2
1 20
Think: 基本的排序二叉树的题,如果是排序二叉树的升级版(平衡二叉树)的话就棘手了,因为在建树的过程中还要满足左右子树的深度(高度)差保持1(|1|)。本题就不用考虑这点。。。不过后台的数据似乎有坑点,在排序建树过程中“存在”两个节点数值相同的情况?我一开始做 的时候:如果当前的值比根大则在此根的右子树上继续判断(如果右子树不存在,当前值就成为此根的右子树了),如果小的话,类似。。。不过问题就出在这里,我要么大要么小,符合定义,不过如果数据值相同怎么办?(超时了。。。)所以我后来改为要么大要么else。。。就AC了。另外听名字“排序二叉树”,中序遍历的结果会是一组有序的序列(好神奇O(∩_∩)O哈哈~
纯C代码如下:(说实话我的代码有点长。。。)
#include<stdio.h>
#include<malloc.h>
#define OVERFLOW -1
typedef struct node
{
int data;
struct node *l, *r;
}Lnode;
int f; //因为输出要求相邻两个数之间用空格隔开,最后一个数后没空格23333
Lnode *Creat(int n); //创建有N个节点的排序二叉树
void mid(Lnode *t); //中序输出排序二叉树
int main()
{
int n;
while(scanf("%d", &n) != EOF){
if(n > 0){
Lnode *t;
t = NULL;
f = 0;
t = Creat(n);
mid(t);
printf("\n");
}
}
return 0;
}
Lnode *Creat(int n)
{
Lnode *head, *pr, *p;
head = (Lnode *)malloc(sizeof(Lnode)); //祖宗节点
if(!head)
exit(OVERFLOW);
head->l = NULL;
head->r = NULL;
int i;
scanf("%d", &head->data); //先解决祖宗节点问题N==1
for(i = 2; i <= n; i++){
p = (Lnode *)malloc(sizeof(Lnode));
if(!p) //开辟空间失败,结(不)束(能)程(玩)序(耍)2333
exit(OVERFLOW);
p->l = NULL;
p->r = NULL;
scanf("%d", &p->data);
pr = head; //每次从祖宗开始比较,接着下一代下一代~哈哈~
while(pr){
if(p->data > pr->data){ //如果当前值比“根”的值大,在右子树
if(pr->r == NULL){ //如果这个跟无右子树
pr->r = p; //那么当前的值就为它的右子树了
break;
}
else pr = pr->r; //否则与其右子树上的节点比较出适合的位置
}
else{ //Think里我说的直接else情况
if(pr->l == NULL){
pr->l = p;
break;
}
else pr = pr->l;
}
}
}
return head; //返回祖宗节点
}
void mid(Lnode *t) //中序遍历访问输出
{
if(t){
mid(t->l); //递归调用自身。。。
if(!f){ //如果f==0
printf("%d", t->data); //后面没空格,只有一个节点的情况也适用
f++; //本身+1 //Yeah
}
else printf(" %d", t->data); //从第二个节点到最后就输出前有空格了
mid(t->r);
}
return ;
}