Complete Binary Search Tree 完全二叉搜索树

题目:https://pintia.cn/problem-sets/16/problems/669

完全二叉搜索树=完全二叉树+二叉搜索树。从树的形状上来看,一定是从上至下、从左至右摆满的。而树的插入跟输入顺序一点关系也没有,题目中说明了:给定一组输入数据,有唯一的完全二叉搜索树与之对应。

测试样例为:10

      1 2 3 4 5 6 7 8 9 0

先来手动建立一下这棵树,有了以下的发现:

  1. 给定结点数量后,根结点的左右子树各自结点数是可以计算的。
  2. 根结点可以被唯一确定,即它的大小排在左子树后面。
  3. 左右子树均为完全二叉搜素树。

有了上面几个条件,我们只需要:

  1. 将输入数据排序,存放在数组中。
  2. 递归地确定每一个结点。

代码:

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 1001

typedef struct Node* List;
struct Node {
    int data;
    List next;
};

int sortdata[MAXSIZE];
int treedata[MAXSIZE];

void sort(int n){
    if (n == 0)
        return;
    List head = (List)malloc(sizeof(struct Node));
    head->data = -1;
    head->next = NULL;
    int i;
    List p, q, neww;
    int num;
    for (i = 0;i < n;i++) {
        q = head;
        p = q->next;
        scanf("%d", &num);
        while (num > q->data) {
            if (q->next == NULL) {
                p = NULL;
                break;
            }
            else {
                if (num < q->next->data) {
                    p = q->next;
                    break;
                }
                q = q->next;
            }
        }
        neww = (List)malloc(sizeof(struct Node));
        neww->data = num;
        if (p)
            neww->next = p;
        else
            neww->next = NULL;
        q->next = neww;
    }
    p = head->next;
    i = 1;
    while (p) {
        sortdata[i] = p->data;
        p = p->next;
        i++;
    }
    return;
}
int calcu(int num) {
    int i = 0;
    int mult = 1;
    int dep=0;
    int count = 0;
    if (num == 1)
        return 0;
    while (mult <= num) {
        mult *= 2;
        dep = mult/2;
        count += dep;
        i++;
    }
    count -= dep;
    int add = (num-count) > (dep/2) ? (dep / 2) : (num - count);
    return (num-1-num+count)/2+add;
}

void Built(int root, int start, int end) {
    if (start == end) {
        treedata[root] = sortdata[start];
        return;
    }
    if (start > end)
        return;
    int mid = start + calcu(end - start + 1);
    treedata[root] =sortdata[mid];
    Built(root * 2, start, mid - 1);
    Built(root * 2 + 1, mid + 1, end);
    return;
}


int main() {
    int N;
    scanf("%d", &N);
    sort(N);
    int i;
    Built(1, 1, N);
    for (i = 1;i <= N;i++) {
        printf("%d", treedata[i]);
        if (i != N)
            printf(" ");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yaotong0830/p/14364290.html