1099. Build A Binary Search Tree (30)

来源:互联网 发布:网络推广属于什么部门 编辑:程序博客网 时间:2024/06/01 16:22

1099. Build A Binary Search Tree (30)

时间限制
100 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
  • Both the left and right subtrees must also be binary search trees.

    Given the structure of a binary tree and a sequence of distinct integer keys, there is only one way to fill these keys into the tree so that the resulting tree satisfies the definition of a BST. You are supposed to output the level order traversal sequence of that tree. The sample is illustrated by Figure 1 and 2.

    Input Specification:

    Each input file contains one test case. For each case, the first line gives a positive integer N (<=100) which is the total number of nodes in the tree. The next N lines each contains the left and the right children of a node in the format "left_index right_index", provided that the nodes are numbered from 0 to N-1, and 0 is always the root. If one child is missing, then -1 will represent the NULL child pointer. Finally N distinct integer keys are given in the last line.

    Output Specification:

    For each test case, print in one line the level order traversal sequence of that tree. All the numbers must be separated by a space, with no extra space at the end of the line.

    Sample Input:
    91 62 3-1 -1-1 45 -1-1 -17 -1-1 8-1 -173 45 11 58 82 25 67 38 42
    Sample Output:
    58 25 82 11 38 67 45 73 42
  • 解析:

    1,二叉树的表示方法有三种,数组表示法,二叉树结构数组表示法,链表结构表示法,本题用的是结构数组表示法.

    2,PAT的题目还是很普通的,掌握几种常用的数据结构设计方案,以及相应的算法,就可以搞定大部分题目.

    3,先想几个简单的问题:

    3.1 给定一个数子序列,构造二叉查找树是不唯一的;

    3.2 不仅是不唯一,而且是可以构造出任意形状的二叉查找树;

    3.3 同一个形状的二叉查找树,会不会有多个,不会,可以从根结点往下考虑,首先根结点必须相同,否则两棵树对应的左右两边个数不会相等,用数学归纳法知,所有元素一一对应相等;

    3.4 中序遍历二叉查找树出来的结果就是元素递增排序,为什么?因为 {左子树}  < 根 < {右子树}, 那么再展开子树到叶子结点,再去掉{}后就是a1 < a2 < a3 < a4....这个样子;

    3.5 反过来,一棵树中序遍历展开后是升序,是否这棵树是二叉查找树, 答案是, 从根结点往下考虑,用数学归纳法,所以二叉查找树还可定义,中序遍历升序,则为二叉查找树;

    3.6 根据上面推出来的二叉查找树等价定义, 将二叉树的结点按中序遍历展开,把给定的元素按生序排列, 对应填入到结点中, 即可构造出一棵二叉查找树.

    代码如下:

    /*************************************************************************> File Name: 1099.c> Author: YueBo> Mail: yuebowhu@163.com> Created Time: Sun 21 May 2017 07:45:35 AM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>int idx = 0;int cmp(const void *a, const void *b){    return *(int *)a - *(int *)b;}typedef struct{    int data;    int left;    int right;} node;void InorderBuildTree(node *treeArr, int *elements, int root){    if (root == -1)        return;    InorderBuildTree(treeArr, elements, treeArr[root].left);    treeArr[root].data = elements[idx];    idx++;    InorderBuildTree(treeArr, elements, treeArr[root].right);}void printfLevelOrder(node *treeArr, int root)  {      node qu[1024];      int front, rear;            front = rear = -1;      if (root == -1)          return;      rear++;      qu[rear].data = treeArr[root].data;      qu[rear].left = treeArr[root].left;      qu[rear].right = treeArr[root].right;            while (rear != front)      {          if (front != -1)              printf(" ");          printf("%d", qu[++front].data);          if (qu[front].left != -1)          {   rear++;              qu[rear].data = treeArr[qu[front].left].data;              qu[rear].left = treeArr[qu[front].left].left;              qu[rear].right = treeArr[qu[front].left].right;                                }          if (qu[front].right != -1)          {   rear++;              qu[rear].data = treeArr[qu[front].right].data;              qu[rear].left = treeArr[qu[front].right].left;              qu[rear].right = treeArr[qu[front].right].right;          }      }      printf("\n");  }  int main(){    int N;    node treeArr[128];    int i;    int elements[128];    scanf("%d", &N);    for (i = 0; i < N; i++)        scanf("%d%d", &treeArr[i].left, &treeArr[i].right);    for (i = 0; i < N; i++)        scanf("%d", elements+i);    qsort(elements, N, sizeof(elements[0]), cmp);    InorderBuildTree(treeArr, elements, 0);    printfLevelOrder(treeArr, 0);        return 0;}

    代码说明:上面的代码中在递归构造二叉查找树函数void InorderBuildTree(node *treeArr, int *elements, int root)使用了idx这个全局变量,以后再改进这段代码,争取使这个函数保持独立性.

    原创粉丝点击