快速排序图解/动画及C语言实现

快速排序图解/动画及C语言实现

介绍

算法名称:快速排序
实现语言:C
作者:nrxsh

算法动画

在这里插入图片描述

算法思路

以从小到大排序为例:

  1. 首先先从一边(左右都行)选择一个关键值,图中的 P 标签就是关键值。

  2. 然后在除 P 外的所有元素两端去 L 和 R 。

 **第一次扫描前取 L R P 的情况**

  1. 从 L 开始往 R 扫描 , 每次检查 L 当前指的元素是否大于 P 。如果当前元素大于 P ,则 L 停止扫描,R 开始往 L 扫描比 P 小的值。如果 R 扫描到了一个比 P 小的值时结束扫描,L 和 R 位置的两个元素交换值之后 继续重复当前步骤。直到 L 和 R 指向同一个元素为止。
  2. 当 L 和 R 指向同一个元素时 比较该元素与 P 所指向的元素的值 , 如果该元素比 P 大 则交换两元素的位置。然后检测集合是否已经有序,如果已有序则结束排序,否则技术当前扫描执行第五步。
  3. 从 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 为止*/
}
  • 17
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值