原题
A Cartesian tree is a binary tree constructed from a sequence of distinct numbers. The tree is heap-ordered, and an inorder traversal returns the original sequence. For example, given the sequence { 8, 15, 3, 4, 1, 5, 12, 10, 18, 6 }, the min-heap Cartesian tree is shown by the figure.
Your job is to output the level-order traversal sequence of the min-heap Cartesian tree.
Input Specification:
Each input file contains one test case. Each case starts from giving a positive integer N (≤30), and then N distinct numbers in the next line, separated by a space. All the numbers are in the range of int.
Output Specification:
For each test case, print in a line the level-order traversal sequence of the min-heap Cartesian tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line.
Sample Input:
10
8 15 3 4 1 5 12 10 18 6
Sample Output:
1 3 5 8 4 6 15 10 12 18
简单分析
- 找到最小的(i)插入到根节点
- 从i左边到开头找到最小的插入左孩子
- 从i右边到末尾找到最小的插入右孩子
- 以此循环2,3
- 最后层序输出
进一步分析
- 在树的几种遍历算法中与 二叉排序树的插入十分类似
- 在全部步骤中都有一步——找到最小-》因此单独拉出来作为模块函数
- 如何判断“左边/右边”的问题,通过stl库函数——map记录序号,通过序号大小来定位左右
- 对于层序输出,也可采用现成stl库函数——队列进行实现
其实能想到二叉排序树,剩下难点就是如何用程序来量化左右的问题
代码
#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<queue>
#include<algorithm>
#include<map>
#define max 30
using namespace std;
typedef struct BTNode {
int key;
struct BTNode* lchild;
struct BTNode* rchild;
}BiTree;
int FindSmall(int begin1, int end2, int a[]);
BiTree* BstInsert(BiTree* T, int a[], int be, int en, int sm, map<int, int>mp);
void PrintTree(BiTree* T);
int main() {
map<int, int>mp;
int number = 0;
scanf("%d", &number);
int a[30], i = 0;
//int* a = (int*)malloc(sizeof(int) * number);用malloc定义变量数组
for (i = 1; i <= number; i++) {
scanf("%d", &a[i]);
mp[a[i]] = i;//对序号进行映射
}
int begin, end, small;
begin = 1, end = number;
small = FindSmall(begin, end, a);
BiTree* root = NULL;
root = BstInsert(root, a, begin,end,small, mp);
PrintTree(root);
return 0;
}
int FindSmall(int begin1, int end2, int a[]) {
int small, i;
small = a[begin1];
for (i = begin1 + 1; i <= end2; i++) {
small = min(small, a[i]);
}
return small;
}
BiTree* BstInsert(BiTree * T, int a[],int be ,int en,int sm , map<int, int>mp) {
if (T == NULL) {
T = (BiTree*)malloc(sizeof(BiTree));
T->key = sm;
T->lchild = T->rchild = NULL;
}
int len;
len = mp[sm] - 1;
if(len-be>=0) {
int LeftSmall;
LeftSmall = FindSmall(be,len, a);
T->lchild = BstInsert(T->lchild, a, be, len, LeftSmall, mp);
}
be = mp[sm] + 1;
if(en - be >= 0) {
int RightSmall;
RightSmall = FindSmall(be, en, a);
T->rchild = BstInsert(T->rchild, a, be, en, RightSmall, mp);
}
return T;
}
void PrintTree(BiTree* T) {
queue<BiTree*> b;
if (T != NULL) {
b.push(T);
while (b.empty() != true) {
if (b.front()->lchild != NULL)
b.push(b.front()->lchild);
if (b.front()->rchild != NULL)
b.push(b.front()->rchild);
printf("%d ", b.front()->key);
b.pop();
}
}
}