希爾排序
先將整個待排元素序列分割成若干個子序列(由相隔某個“增量”的元素組成的)分別進行直接插入排序,然後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。
增量increment
增量初始值設置爲length(待排序的數組長度)/2
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
void Shellsort(int a[],int length)
{
int i,j;
int increment=length;
do
{
increment/=2;
for(int i=increment+1;i<=length;i++)
{
if(a[i]<a[i-increment])
{
a[0]=a[i];
for(j=i-increment;j>0&&a[0]<a[j];j-=increment)
{
a[j+increment]=a[j];
}
a[j+increment]=a[0];
}
}
}
while(increment>1);
for(int i=1;i<=length;i++)
printf("%d ",a[i]);
}
int main()
{
int n,a[1001];
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
Shellsort(a,n);
return(0);
}
後面我看到一個大佬的代碼,簡潔很多(易背難懂)
void shellsort3(int a[], int n)
{
int i, j, gap;
for (gap = n / 2; gap > 0; gap /= 2)
for (i = gap; i < n; i++)
for (j = i - gap; j >= 0 && a[j] > a[j + gap]; j -= gap)
swap(a[j], a[j + gap]);
}
希爾排序也是一種不穩定的排序,在合適的增量其時間複雜度比冒泡的O(n平方)要快!!
堆排序
學堆排序之前要了解什麼是堆,堆就是具有特殊性質的完全二叉樹,比如圖一父節點比子節點都大,這就是最大堆,相反圖二就是最小堆。
步驟就是把待排序的數組先構造成一個堆(這裏要利用完全二叉樹的性質,比如在數組裏面父節點的序號是i,那左孩子一定是2*i,右孩子一定是2
*i+1),然後再構造成一個最大堆,就得到了一個有序的序列。
排序算法時間複雜度分析