1099. Build A Binary Search Tree (30)
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:9 1 6 2 3 -1 -1 -1 4 5 -1 -1 -1 7 -1 -1 8 -1 -1 73 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这个全局变量,以后再改进这段代码,争取使这个函数保持独立性.