#include <stdio.h>
#include <iostream>
using namespace std;
const int N = 1000;
int tree[N];
void heapify(int tree[], int n, int i){ // 当两个子节点都是堆时, 可以直接递归形成堆。
if(i > n){
return ;
}
int c1 = i * 2;
int c2 = i * 2 + 1;
int max = i;
if(c1<=n && tree[c1] > tree[max]){
max = c1;
}
if(c2<=n && tree[c2] > tree[max]){
max = c2;
}
if(max!=i){
swap(tree[max],tree[i]);
heapify(tree, n, max); //确保调换过后子节点也是堆。
}
}
void build_heap(int tree[], int n){
int parent = n / 2;
for(int i = parent; i > 0 ; i--){
heapify(tree, n, i);
}
return ;
}
void heap_sort(int tree[], int n){
build_heap(tree, n);
for(int i = n; i > 0; i--){
swap(tree[i], tree[1]); // 大根堆,从最大值到最小值降序排序。 每一次swap,都有一个当前最大值被排好序。
heapify(tree, i-1, 1);
}
}
int main(){
int n;
cin>>n;
for(int i = 1; i <= n; i++) cin>>tree[i]; // 下标从 1 开始存。
heap_sort(tree, n);
for(int i = 1; i <= n; i++) cout<<tree[i]<<endl;
return 0;
}