五、希爾排序
希爾排序我們需要藉助變量gapk來實現(gap是變量名,k是下腳標),這個排序算法主要是通過比較相距gapk間隔的元素值的大小來進行排序,並且在一組數據當中,所有相距gapk的元素都被排序。
希爾排序的思路是:確定一個元素間隔gap,將參加排序的元素從第一個元素開始按照這個間隔依次分成多個子序列,分別將所有位置的相隔gap的元素看成一個子序列。例如對於一組數據{2,9,3,7,10,1,5,4,6,8}來說,我們以gap = 4來進行劃分,則是如下這個樣子的:
序列一:2 9 3 7 10 1 5 4 6 8 ——對2,和10進行排序
序列二:2 9 3 7 10 1 5 4 6 8——對9和1進行排序
序列三:2 9 3 7 10 1 5 4 6 8——對3和5進行排序
序列四:2 9 3 7 10 1 5 4 6 8——對7和4進行排序
序列五:2 9 3 7 10 1 5 4 6 8——對10和6進行排序
序列六:2 9 3 7 10 1 5 4 6 8——對1和8進行排序
在這個例子中,我們把數據劃分成了六個子序列,對於每個子序列,我們可以採用其他排序算法,如冒泡排序、插入排序等,然後縮小gap的值,按照新的gap值劃分數組,再分別對每個子序列排序……以此類推,直到gap值遞減爲1。
關於gap:目前較爲流行的gap的選擇方法是採用shell方法,即:每次gap值都減半。例如,還是以上面那組數據{2,9,3,7,10,1,5,4,6,8}爲例:
初始狀態:2 9 3 7 10 1 5 4 6 8
第一趟:gap = 4,排序結果:2 1 3 4 6 8 5 7 10 9
第二趟:gap = 2,排序結果:2 1 3 4 5 7 6 8 10 9
第三趟:gap = 1,排序結果:1 2 3 4 5 6 7 8 9 10
排序結束。
代碼:
#include<iostream>
using namespace std;
void Swap(int* a,int* b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void shellSort(int a[],int n)
{
int i,j,flag,counter = 1;
int gap = n;
while(gap>1)
{
gap = gap/2; ///每次gap都減半。
do///子序列排序我們這裏採用冒泡排序的方法。
{
flag = 0;
for(i=0;i<=n-gap-counter;i++)
{
j = i+gap;
if(a[i]>a[j])
{
Swap(&a[i],&a[j]);
flag = 1;
}
}
}while(counter<n&&flag==1);
}
}
六、選擇排序
選擇排序的思想是:重複的從待排序的元素中挑選出最大的或者最小的元素進行排序。我們選擇從小到大的選擇最大元素進行排序的方式進行講解。
選擇排序的基本思路是:第i趟排序從待排序的前n-i+1個元素裏面選出最大的元素,並與這n-i+1個元素的最末位置的元素進行交換,知道i = n-1 。也就是說,選擇排序最多進行n-1趟。
我們還以{2,9,3,7,10,1,5,4,6,8}舉例,其中{}代表整個數據的集合,“()”代表已經排好的元素
初始狀態:2 9 3 7 10 1 5 4 6 8
第一趟:所有元素中10最大,與最末位置的8進行交換,得到:2 9 3 7 8 5 4 6 1(10)
第二趟:剩餘的元素中9最大,與最末位置的1進行交換,得到:2 1 3 7 8 5 4 6 (9 10)
第三趟:剩餘的元素中8最大,與最末位置的6進行交換,得到:2 1 3 7 6 5 4 (8 9 10)
第四趟:剩餘的元素中7最大,與最末位置的4進行交換,得到:2 1 3 4 6 5 (7 8 9 10)
……
以此類推
第九趟:排序完成得到:(1 2 3 4 5 6 7 8 9 10)
代碼:
#include<iostream>
using namespace std;
void selectionSort(int a[],int n)
{
int i = 1;
int Max; ///用於記錄每趟排序中最大的那個元素。
int temp;
while(i<n)
{
Max = n-i;///將Max初始化爲待排元素最末位置
for(int j=0;j<n-i+1;j++)
{
if(a[j]>a[Max])
{
Max = j;
}
}
if(Max!=n-i) ///將最大元素與最末元素進行交換
{
temp = a[Max];
a[Max] = a[n-i];
a[n-i] = temp;
}
i++;
}
}