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;
}