1.排序優化思想
其實吧,按照博主目前的人生經歷來說,優化算法,都會從一個基本的思想出發,操作有效性,爲什麼這麼說。操作有效性就區別了高效率的算法和暴力算法。下列從排序算法祖宗冒泡算法和新生代快速排序作比較。
大家對冒泡算法不太熟悉的可以參考我的上一篇博客:
算了,先說說快排基本思想再做比較吧,順序亂了ahhh
2.單邊循環法的快速排序
總的來說,快速排序利用的就是分治算法,分治算法的基本排序思想是,我選擇一個基準元素,講其他元素排到正確的區域(而不是精確的位置),比如,大過我的排我左邊,小的排我右邊。熟不熟悉,小學我們就是這樣排隊的,沒想到大學就忘了。。。。(此處總結,真的很多算法都是生活中可以找到的,但我們稱爲意識,計算機稱爲算法)
排序數列:
確定基準元素,選取第一個爲基準元素:
(升序排序)遍歷數列,和基準元素比較,小於則 mark++ ,並將當前元素替換,例如接下來兩步操作:
遍歷7,大於4,無操作:
遍歷3,小於4,mark++,替換元素:
經過一輪比較之後,就會出現如下序列:
最後一步就是mark 和 基準位置元素調換。這樣基準元素就已經是精準定位了:
現在可以看出mark左右都是相對有序的了,左邊比4小,右邊比4大,相對於冒泡過程的話,既完成了4元素的精準定位,又將接下來排序範圍縮小,效率更高,接下來就是遞歸完成剩下排序了,詳情看代碼。
3.算法實現
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
*@brief: 分治算法
*@param1: 排序的數組
*@param2: 排序區間,開始index
*@param3: 排序區間,結束index
*@reval: 返回基準元素index
*/
int partition(int *array, int startIndex, int endIndex) {
//選取第一個index作爲pivot
int pivot = array[startIndex];
int mark = startIndex;
for (int i = startIndex + 1; i <= endIndex; i++) {
//升序
if (array[i] < pivot) {
mark++;
//以下代碼對於相等元素出現Bug(...)慎用, index : mark = i
/*array[i] = array[mark] + array[i];
array[mark] = array[i] - array[mark];
array[i] = array[i] - array[mark];*/
int tmp = array[i];
array[i] = array[mark];
array[mark] = tmp;
}
}
array[startIndex] = array[mark];
array[mark] = pivot;
return mark;
}
/*
*@brief: 快速排序算法
*@param1: 排序的數組
*@param2: 排序區間,開始index
*@param3: 排序區間,結束index
*@reval: None
*/
void quicksort(int *array, int startIndex, int endIndex) {
if (startIndex >= endIndex) {
return;
}
int mark = partition(array, startIndex, endIndex);
//遞歸
quicksort(array, startIndex, mark - 1);
quicksort(array, mark + 1, endIndex);
}
int main() {
//int array[] = { 5, 1, 6, 3, 9, 2, 8, 7 };
int array[] = { 4, 7, 3, 5, 6, 2, 8, 1 };
int len = 8;
quicksort(array, 0, len - 1);
for (int i = 0; i < len; i++) {
printf("%d\t", array[i]);
}
printf("\n");
system("pause");
return 0;
}