1.插入排序
由N-1趟排序組成,對於p=1到p=N-1趟,插入排序保證從位置0到位置p上的元素為已排序狀態。
時間複雜度:O(N^2)
代碼
void InsertionSort(ElementType A[],int N)
{
int j,p;
ElementType Tmp;
for(p=1;p<N;p++)
{
Tmp=A[j];//把A[j]儲存下來,因為它要被插入到前面的某個位置去
for(j=p;j>0&&A[j-1]>Tmp;j--)//大於A[j]的元素逐個後移
{
A[j]=A[j-1];
}
A[j]=Tmp;
}
}
2.希爾排序
希爾排序使用一個序列h1,h2,h3,ht,叫做增量排序。在使用增量hk的一趟排序之後,對於每個i我們有A[i]<A[i+hk],所有相隔hk的元素被排序。
時間複雜度:O(N^(1+a)),其中0<a<1。
代碼
//代碼不太好理解,使用了3層迴圈
void ShellSort(ElementType A[],int N)
{
int j,p,Increment;
ElementType Tmp;
for(Increment=N/2;Increment>0;Increment/=2)
{
for(p=Increment;p<N;p++)
{
Tmp=A[p];
for(j=p;j>=Increment;j-=Increment)
{
if(A[j]<A[j-Increment])
A[j]=A[j-Increment];
else
break;
}
A[j]=Tmp;
}
}
}
3. 堆排序
思想:建立小頂堆,然後執行N次deleteMin操作。
時間複雜度:O(NlogN),實踐中,慢於sedgewick的希爾排序
空間複雜度:O(N),用於建立堆得數組
4.歸併排序
使用遞迴把數組分為兩部分分別排序,然後合并成一個數組
時間複雜度:O(NlogN)
空間複雜度:O(N)
代碼
void Merge(ElementType A[],ElementType TmpArray[], int Lpos, int Rpos, int RightEnd)
{
int i, LeftEnd, NumELements,TmpPos;
LeftEnd=Rpos-1;
TmpPos=Lpos;
NumElements=RightEnd-Lpos+1;
while(Lpos<=LeftEnd&&Rpos<=RightEnd)
TmpArray[TmpPos++]=(A[Lpos]<A[Rpos])?A[Lpos++]:A[Rpos++];
while(Lpos<LeftEnd)
TmpArray[TmpPos++]=A[Lpos++];
while(Rpos<RightEnd)
TmpArray[TmpPos++]=A[Rpos++];
for(i=0;i<NumElements;i++,RightEnd--)
A[RightEnd]=TmpArray[RightEnd];
}
5.快速排序
對於小數組(N<20),快排不如插排好。一種好的截止範圍是N=10,大於10則用快排。
快排的四步:
①如果S中元素個數是0或1,則返回
②取S中間元素v為樞紐元
③將S-{v}分成兩個不相交的集合:分別是S1(小於v),和大於v的部分S2
④返回quicksort(S1),繼隨v,繼而quicksort(S2)
時間複雜度:O(NlogN)
編程思想:1.選取樞紐元,取首尾及中間的三個元素,排序,小的排在首位,大的排在尾部,中的作為樞紐元
2.排序時把樞紐元放在Right-1的位置上,i=Left+1;j=Right-2;開始交換過程
代碼
ElementType Median3(ElementType A[],int Left, int Right)
{
int center =(Left+Right)/2;
if(A[Left]>A[Center])
swap(&A[Left],&A[Center]);
if(A[Left]>A[Right])
swap(&A[Left],&A[Right]);
if(A[Center]>A[Right])
swap(&A[Center],&A[Right]);
swap(&A[Center],&A[Right-1]);
return A[Right-1];
}
Qsort(ElementType A[],int Left,int Right)
{
int i,j;
ElementType Pivot;
if(Left+9<Right) //10個元素以上的數組使用快排
{
Pivot=Median3(A[],Left,Right);
i=Left+1;
j=Right-2; while(1) {
while(A[i++]<Pivot);
while(A[j--]>Pivot);
if(i<j)
swap(&A[i],&A[j])
else
break; }
swap(&A[i],&A[Right-1]);
Qsort(A,Left,i-1);
Qsort(A,i+1,Right);
}
else
InsertSort(A,Right-Left+1);
}
6.直接選擇排序
描述:選出數組中最小的元素,與數組的第一個元素交換;然後選擇出數組中次小的元素,與與第二個元素交換,直到完成
選擇排序需要比較N(N-1)/2次,即N2次,而交換則只需要N-1次
對於是否已經排好序,或者隨機檔案,所花費的時間是一致的,即執行時間具有強迫性
選擇排序應用在資料項目比較大,鍵比較小的情況下,因為此時移動元素花費時間較多,而對於其他排序演算法,元素移動頻繁的多
代碼
void sort(ElementType A[], int N)
{
int i, j;
int min;
for(i=0; i<N-1; i++)
{
min = i;
for(j=i+1; j<=N-1; j++)
if(A[j]<A[min]) min=j;
swap(A[i],A[min]);
}
}