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.数组
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.函数
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.spa
10 8 15 3 4 1 5 12 10 18 6`
1 3 5 8 4 6 15 10 12 18
现给定一颗笛卡尔树的中序序列,它知足小根堆的性质,如今须要输出其层序遍历。3d
大体思路就是建树和层序遍历,其惟一的难点在于建树,其实只要知道了根节点的位置就不是问题,首先咱们如今有这颗树的中序序列,保存在origin数组中,同时使用unordered_map<int,int> pos
保存每个节点在中序序列中的位置,建树的关键是得只要每个子树的根节点和在中序遍历中的位置,这里的子树都知足小根堆的性质,说明在[inL,inR]之间最小的数字就是当前子树的根节点,那么咱们使用getMin得到original中的[left,right]最小的那个数字,代码以下:code
// 在original的[left,right]中找到最小的那个数字 int getMin(int left,int right){ int Min = 0x3fffffff; for(int i=left;i<=right;++i){ Min = Min>original[i]?original[i]:Min; } return Min; }
接下来就能够使用createTree函数来进行建树了,代码以下:blog
Node* createTree(int inL,int inR){ if(inL>inR) return nullptr; Node* root = new Node; root->data = getMin(inL,inR); int k = pos[root->data];// 根节点的位置 //[inL,k-1]为左子树 root->left = createTree(inL,k-1); //[k+1,inR]为右子树 root->right = createTree(k+1,inR); return root; }
最后就是层序遍历并输出。ci
#include<cstdio> #include<queue> #include<unordered_map> using namespace std; struct Node{ int data; Node *left; Node *right; }; int original[40]; unordered_map<int,int> pos;// 每个节点在中序序列中的位置 // 在original的[left,right]中找到最小的那个数字 int getMin(int left,int right){ int Min = 0x3fffffff; for(int i=left;i<=right;++i){ Min = Min>original[i]?original[i]:Min; } return Min; } Node* createTree(int inL,int inR){ if(inL>inR) return nullptr; Node* root = new Node; root->data = getMin(inL,inR); int k = pos[root->data];// 根节点的位置 //[inL,k-1]为左子树 root->left = createTree(inL,k-1); //[k+1,inR]为右子树 root->right = createTree(k+1,inR); return root; } int num = 0; void BFS(Node* root){ queue<Node*> q; q.push(root); while (!q.empty()){ Node* t = q.front(); q.pop(); if(num==0){ printf("%d",t->data); ++num; } else { printf(" %d",t->data); } if(t->left){ q.push(t->left); } if(t->right){ q.push(t->right); } } } int main(){ int N; scanf("%d",&N); for (int i = 0; i < N; ++i) { scanf("%d",&original[i]); pos[original[i]] = i; } Node* root = createTree(0,N-1); BFS(root); return 0; }