繼續講排序的方法
堆排序:
void heapify(int *a, int i, int len)
{
int left = 2 * i + 1;
int right = 2 * i + 2;
int max = i;
if(left < len && a[left] > a[max])
max = left;
if(right < len && a[right] > a[max])
max = right;
if(max != i)
{
swap(a, i, max);
heapify(a, max, len);
}
}
void heap_sort(int *a, int len)
{
int i;
for(i = len/2 - 1; i >= 0; i--)
{
heapify(a, i, len);
}
for(i = len - 1; i >= 0; i--)
{
swap(a, 0, i);
len--;
heapify(a, 0, len);
}
}
堆排序是指利用堆積樹(堆)這種數據結構所設計的一種排序算法,它是選擇排序的一種。可以利用數組的特點快速定位指定索引的元素。堆分爲大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即A[PARENT[i]] >= A[i]。在數組的非降序排序中,需要使用的就是大根堆,因爲根據大根堆的要求可知,最大的值一定在堆頂。
快速排序:
int quick(int *a, int left, int right)
{
int piovt = a[right];
int index = left;
int i;
for(i = left; i < right; i++)
{
if(a[i] < piovt)
{
swap(a, i, index);
index++;
}
}
swap(a, index, right);
return index;
}
void qSort(int *a, int left, int right)
{
if(left < right)
{
int piovt = quick(a, left, right);
qSort(a, left, piovt - 1);
qSort(a, piovt + 1, right);
}
}
快速排序的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
歸併排序:
void merge(int *a, int left, int mid, int right, int *tmp)
{
int i = left;
int j = mid + 1;
int k = 0;
while(i <= mid && j <= right)
{
if(a[i] > a[j])
{
tmp[k++] = a[j++];
}
else
{
tmp[k++] = a[i++];
}
}
while(i <= mid)
{
tmp[k++] = a[i++];
}
while(j <= right)
{
tmp[k++] = a[j++];
}
k = 0;
for(i = left; i <= right; i++)
{
a[i] = tmp[k++];
}
}
void mergeSort(int * a, int left, int right, int *tmp)
{
if(left >=right)
return;
int mid = (left + right) / 2;
mergeSort(a, left, mid, tmp);
mergeSort(a, mid + 1, right, tmp);
merge(a, left,mid,right,tmp);
}
歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。
歸併過程爲:比較a[i]和b[j]的大小,若a[i]≤b[j],則將第一個有序表中的元素a[i]複製到r[k]中,並令i和k分別加上1;否則將第二個有序表中的元素b[j]複製到r[k]中,並令j和k分別加上1,如此循環下去,直到其中一個有序表取完,然後再將另一個有序表中剩餘的元素複製到r中從下標k到下標t的單元。歸併排序的算法我們通常用遞歸實現,先把待排序區間[s,t]以中點二分,接着把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸併操作合併成有序的區間[s,t]。
以上三種排序都用到了遞歸的思想,由此可見遞歸在我們的學習中是多麼的重要。