北邮1467二叉树题引起的思考
- 题目描述:
-
二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树:
1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值;
2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值;
3. 左、右子树本身也是一颗二叉排序树。
现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。
- 输入:
-
输入包含多组测试数据,每组测试数据两行。
第一行,一个数字N(N<=100),表示待插入的节点数。
第二行,N个互不相同的正整数,表示要顺序插入节点的关键字值,这些值不超过10^8。
- 输出:
-
输出共N行,每次插入节点后,该节点对应的父亲节点的关键字值。
- 样例输入:
-
5 2 5 1 3 4
- 样例输出:
-
-1 2 2 5 3
我先Runtime Error,后Time Limit Exceed, 然后才AC;每次出问题都发现了一些问题,记录一下:- RE版代码(你能看出来问题吗?)
View Code1 #include <stdio.h> 2 #include <string.h> 3 int btree[101]; 4 5 int main(int argc, const char *argv[]) 6 { 7 memset(btree, 0, 101*sizeof(int)); 8 int data, index, parent, count, i; 9 while(scanf("%d", &count)!=EOF) 10 { 11 12 if(scanf("%d", &data)!=EOF) 13 btree[1] = data; 14 printf("-1\n"); 15 for(i=1;i<count;i++) 16 { 17 scanf("%d", &data); 18 index = 1; 19 while(btree[index]!=0) 20 { 21 while(btree[index]!=0&&data>btree[index]) 22 { 23 parent = btree[index]; 24 index=2*index+1; 25 } 26 while(btree[index]!=0&&data<btree[index]) 27 { 28 parent = btree[index]; 29 index=2*index; 30 } 31 } 32 btree[index] = data; 33 printf("%d\n", parent); 34 } 35 } 36 return 0; 37 }
2. TLE版本(问题在哪,为什么会这样,怎么改进,能看出来吗?)
View Code1 #include <stdio.h> 2 #include <string.h> 3 typedef struct btree 4 { 5 unsigned int data; 6 struct btree *lchild; 7 struct btree *rchild; 8 }* bstree; 9 struct btree array[100]; 10 11 int main(int argc, const char *argv[]) 12 { 13 unsigned int data; 14 int count, current=0; 15 bstree root, parent; 16 memset(array, 0, 100*sizeof(struct btree)); 17 while(scanf("%d", &count)!=EOF) 18 { 19 if(count>0) 20 { 21 scanf("%du", &data); 22 array[current].data = data; 23 root = &(array[0]); 24 } 25 printf("-1\n"); 26 for(current=1;current<count;current++) 27 { 28 scanf("%du", &data); 29 array[current].data = data; 30 parent = root; 31 while(1) 32 { 33 if(data>parent->data&&parent->rchild==0) 34 { 35 parent->rchild = &array[current]; 36 break; 37 } 38 else if(data<parent->data&&parent->lchild==0) 39 { 40 parent->lchild = &array[current]; 41 break; 42 } 43 while(data>=parent->data&&parent->rchild!=0) 44 { 45 parent = parent->rchild; 46 } 47 while(data<=parent->data&&parent->lchild!=0) 48 { 49 parent = parent->lchild; 50 } 51 } 52 printf("%d\n", parent->data); 53 } 54 } 55 return 0; 56 } 57
3. AC版本(看看和TLE版本有啥不同,效率差了十万八千里,求解惑)
View Code1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 struct btree 6 { 7 struct btree *lchild, *rchild; 8 unsigned long int data; 9 }; 10 11 struct btree* create_btree(struct btree *t, unsigned long int d, unsigned long int parent); 12 13 int main() 14 { 15 int i, n; 16 unsigned long int d; 17 struct btree *t; 18 19 while (scanf("%d", &n) != EOF) { 20 t = NULL; 21 for (i = 0; i < n; i ++) { 22 scanf("%ld", &d); 23 t = create_btree(t, d, -1); 24 } 25 } 26 27 return 0; 28 } 29 30 struct btree* create_btree(struct btree *t, unsigned long int d, unsigned long int parent) 31 { 32 if (t == NULL) { 33 t = (struct btree *)malloc(sizeof(struct btree)); 34 t->data = d; 35 t->lchild = NULL; 36 t->rchild = NULL; 37 printf("%ld\n", parent); 38 }else if(t->data > d) { 39 t->lchild = create_btree(t->lchild, d, t->data); 40 }else if(t->data < d) { 41 t->rchild = create_btree(t->rchild, d, t->data); 42 }else { 43 exit(EXIT_FAILURE); 44 } 45 46 return t; 47 }
RE版两个问题,在审题上,数据用int不够存,肯定有测试用例不行的;而且int btree[101]是没有道理的,其实如果这么存二叉树,100层想要无措,得要2的99次方个元素,God,思路也不对;
TLE版的算法结果是对的,但是超时了,改成递归建树就好了,效率差了一百倍,为什么呢?