#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N];
/**算法名称:直接插入排序
* 时间复杂度:最好情况:O(n),最坏情况:O(n^2), 平均情况:O(n^2)
* 空间复杂度:O(1)
* 稳定性:稳定
**/
void insert_sort()
{
for (int i = 0; i < n; i ++ )
{
int t = q[i], j = i;
while (j >= 0 && q[j - 1] > t)
{
q[j] = q[j - 1];
j -- ;
}
q[j] = t;
}
}
/**算法名称:折半插入排序
* 时间复杂度:最好情况:O(n),最坏情况:O(n^2), 平均情况:O(n^2)
* 空间复杂度:O(1)
* 稳定性:稳定
**/
void binary_search_insert_sort()
{
for (int i = 0; i < n; i ++ )
{
if (q[i - 1] < q[i]) continue;
int t= q[i];
int l = 0, r = i - 1;
while (l < r)
{
int mid = l + r >> 1;
if (q[mid] <= t) l = mid + 1;
else r = mid;
}
int j = i;
while (j > l)
{
q[j] = q[j - 1];
j -- ;
}
q[l] = t;
}
}
/**算法名称:折半插入排序
* 时间复杂度:最好情况:O(n),最坏情况:O(n^2), 平均情况:O(n^2)
* 空间复杂度:O(1)
* 稳定性:稳定
**/
void bubble_sort()
{
for (int i = 0; i < n; i ++ )
{
int flag = true;
for (int j = n - 1; j > i; j -- )
{
if(q[j] < q[j - 1])
{
flag = false;
swap(q[j], q[j - 1]);
}
}
if (flag) break;
}
}
/**算法名称:简单选择排序
* 时间复杂度:最好情况:O(n^2),最坏情况:O(n^2), 平均情况:O(n^2)
* 空间复杂度:O(1)
* 稳定性:不稳定 如:2 2 1 --swap(q[0],q[3])--> 1 2 2 如果稳定最后一个2应该是在第二个二的前面但实际上不会所以不稳定
**/
void select_sort()
{
for (int i = 0; i < n - 1; i ++ )
{
int t = q[i], tmp = i;
for (int j = i; j < n; j ++ )
{
if (q[j] < t)
{
t = q[j];
tmp = j;
}
}
swap(q[i], q[tmp]);
}
}
/**算法名称:shell排序 公差d 分组内部插入排序
* 时间复杂度:O(n^3/2)
* 空间复杂度:O(1)
* 稳定性:不稳定
**/
void shell_sort()
{
for (int d = n / 3; d; d = d == 2 ? 1 : d / 3)
{
for (int start = 0; start < d; start ++ )
{
for (int i = start + d; i < n; i += d)
{
int t = q[i], j = i;
while (j > start && q[j - d] > t)
{
q[j] = q[j - d];
j -= d;
}
q[j] = t;
}
}
}
}
/**算法名称:快速排序
* 时间复杂度:最好情况:O(nlogn),最坏情况:O(n^2), 平均情况:O(nlogn)
* 空间复杂度:O(logn)
* 稳定性:不稳定
**/
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
/**算法名称:桶排序
* 时间复杂度:O(n + m) n为元素个数 m为元素最大值
* 空间复杂度:O(m)
* 稳定性:稳定
**/
int s[N], w[N];
void bucket_sort(){
//统计每个桶里面应该有多少元素,即小于和等于在该元素左边的个数
for(int i = 0 ;i < n ; i++) s[q[i]]++;
//求所有桶的前缀和(循环到数值的最大范围)
for(int i = 0 ; i < N ; i++) s[i] += s[i - 1];
/*把每个元素放到对应的位置上,一定要从后往前放(稳定),先放到
辅助数组里面,防止产生读写的冲突*/
for(int i = n - 1 ; i >= 0 ; i --) w[-- s[q[i]]] = q[i];
//排完序之后,把序列复制到原数组中去
for(int i = 0 ; i < n ; i++) q[i] = w[i];
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
//insert_sort();
//binary_search_insert_sort();
//bubble_sort();
//select_sort();
shell_sort();
for (int i = 0; i < n; i ++ ) printf("%d ", q[i]);
}