介绍
算法名称:快速排序
实现语言:C
作者:nrxsh
算法动画
算法思路
以从小到大排序为例:
-
首先先从一边(左右都行)选择一个关键值,图中的 P 标签就是关键值。
-
然后在除 P 外的所有元素两端去 L 和 R 。
- 从 L 开始往 R 扫描 , 每次检查 L 当前指的元素是否大于 P 。如果当前元素大于 P ,则 L 停止扫描,R 开始往 L 扫描比 P 小的值。如果 R 扫描到了一个比 P 小的值时结束扫描,L 和 R 位置的两个元素交换值之后 继续重复当前步骤。直到 L 和 R 指向同一个元素为止。
- 当 L 和 R 指向同一个元素时 比较该元素与 P 所指向的元素的值 , 如果该元素比 P 大 则交换两元素的位置。然后检测集合是否已经有序,如果已有序则结束排序,否则技术当前扫描执行第五步。
- 从 P 位置把集合分成左右两个部分,然后对每一部分执行 第一个步骤做循环。
实现代码
代码片
.
/**
* @author nrxsh https://blog.csdn.net/qq_16635277
* 2019-01-20
* original
*/
#include<stdio.h>
#include<process.h>
#define _COUNT 30000
int array[_COUNT];
void readToArray()
{
FILE *fp = fopen("F:\\generates\\C\\randnum50000.txt", "r");
if (fp)
{
int i = 0;
while (fscanf(fp, "%d\n", &array[i++]) != EOF);
fclose(fp);
}
}
void quicksort(int l,int r)
{
int il = l;
int ir = r;
if (l >= r)
return;
int p = r;
while (l != r)
{
while (array[l] <= array[p] && l < r)
l++;
while (array[r] >= array[p] && l < r && r >= 1)
r--;
if (l != r)
{
int temp = array[l];
array[l] = array[r];
array[r] = temp;
}
else
{
if (array[l] > array[p])
{
int temp = array[l];
array[l] = array[p];
array[p] = temp;
}
}
}
p = l;
quicksort(il, p - 1);
quicksort(p + 1, ir);
}
int check() //检查是否成功排序
{
for (int i = 0; i < _COUNT-1; i++)
{
if (array[i] > array[i + 1])
return 0;
}
return 1;
}
int main()
{
readToArray();
int l, r;
l = 0;
r = (sizeof(array) / 4) - 1;
quicksort(l,r);
printf("%d\n",check());
system("pause");
return 0;
}
写完后看了一下 百度百科 上的快速排序算法,人家写的非常简单。但是我认为值得自己研究实现。
百度百科 快速排序算法 c语言
.
void sort(int *a, int left, int right)
{
if (left >= right)/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/
{
return;
}
int i = left;
int j = right;
int key = a[left];
while (i < j) /*控制在当组内寻找一遍*/
{
while (i < j && key <= a[j])
/*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升
序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/
{
j--;/*向前寻找*/
}
a[i] = a[j];
/*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是
a[left],那么就是给key)*/
while (i < j && key >= a[i])
/*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,
因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/
{
i++;
}
a[j] = a[i];
}
a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/
sort(a, left, i - 1);/*最后用同样的方式对分出来的左边的小组进行同上的做法*/
sort(a, i + 1, right);/*用同样的方式对分出来的右边的小组进行同上的做法*/
/*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/
}