04-树6 Complete Binary Search Tree

  本题要求根据输入实现一棵完美二叉搜索树并层序遍历输出。

  以下方法没有构造出树再进行遍历,而是利用完美二叉树中各结点位置的规律逐步得出要求的序列,以数组形式存放最后直接输出。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <math.h>
 4 #define MAXSIZE 1000
 5 
 6 int comp(const void *a, const void *b);
 7 void Func(int* inSeq, int* LevTrSeq, int LeftIndex, int RightIndex, int RootIndex);
 8 int GetLeftNum(int num);
 9 int Min(int a, int b);
10 
11 int main(int argc, char const *argv[])
12 {
13     int N, i;
14     int inSeq[MAXSIZE], LevTrSeq[MAXSIZE];
15     scanf("%d", &N);
16     for (i = 0; i < N; i++){
17         scanf("%d", &inSeq[i]);
18     }
19     qsort(inSeq, N, sizeof(int), comp);
20     int LeftIndex = 0, RightIndex = N - 1, RootIndex = 0; 
21     Func(inSeq, LevTrSeq, LeftIndex, RightIndex, RootIndex);
22     printf("%d", LevTrSeq[0]);
23     for (i = 1; i < N; i++){
24         printf(" %d", LevTrSeq[i]);
25     }
26     printf("\n");
27     return 0;
28 }
29 
30 int comp(const void *a, const void *b)
31 {
32     return *(int*)a - *(int*)b;
33 }
34 
35 void Func(int* inSeq, int* LevTrSeq, int LeftIndex, int RightIndex, int RootIndex)
36 {
37     int num;  //number of elements in this sequence
38     num = RightIndex - LeftIndex + 1;
39     if(!num)
40         return;
41     int LeftNum, LeftRootIndex, RightRootIndex;  //number of nodes in left subtree; substree roots' index
42     LeftNum = GetLeftNum(num);
43     LevTrSeq[RootIndex] = inSeq[LeftIndex + LeftNum];
44     LeftRootIndex = 2 * RootIndex + 1;  //完全二叉树每层最左节点的下标规律如此
45     RightRootIndex = LeftRootIndex + 1;  //因为是层序遍历,输出序列中右子树根节点紧挨着左子树根节点
46     Func(inSeq, LevTrSeq, LeftIndex, LeftIndex + LeftNum - 1, LeftRootIndex);
47     Func(inSeq, LevTrSeq, LeftIndex + LeftNum + 1, RightIndex, RightRootIndex);
48     return;
49 }
50 
51 int GetLeftNum(int num)
52 {
53     int h = 0;  //tree height
54     int i, LowestNum;  //LowestNum is the nodes number of the lowest level
55     int LeftNum;
56     int LastLevelNum = 1;  //each level nodes number
57     int Num = num;  //底下还要用到num,不能直接对其进行操作
58     while(Num > 1){
59         Num /= 2;
60         h++;
61     }
62     for(i = 0; i < h - 1; i++){
63         LastLevelNum *= 2;
64     }
65     //这里的操作务必是上一层全部节点数乘2,不能先乘到最后一层再用除以2操作。
66     //容易除成负数最后负数返回导致数组下标为负出错
67     LowestNum = num - LastLevelNum * 2 + 1;
68     LeftNum = Min(LastLevelNum, LowestNum) + LastLevelNum - 1;
69     return LeftNum;
70 }
71 
72 int Min(int a, int b)
73 {
74     return (a < b) ? a : b;
75 }

 

posted @ 2018-04-02 17:30  BianK  阅读(138)  评论(0编辑  收藏  举报