北邮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;每次出问题都发现了一些问题,记录一下:
  1. RE版代码(你能看出来问题吗?)
View Code
 1 #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 Code
 1 #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 Code
 1 #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版的算法结果是对的,但是超时了,改成递归建树就好了,效率差了一百倍,为什么呢?

原文地址:https://www.cnblogs.com/xuangong/p/3002068.html