十大算法之快速排序(Quick Sort)

目录

 快速排序(Quick Sort)简介:

 算法描述:


动图演示:

          代码实现:


快速排序(Quick Sort)简介:

整体思想,每次都取最左边的数据作为基准值,循环一次后,将基准值放入中间位,即 i == j的位置。此时,基准值在中间,左边都是比基准小的数,右边都是比基准大的数,
之后分别让基准值左边的数据和右边的数据继续执行快速排序,
直到最后i-1 < start ,  i+1 > end,
即左边基准值处于数组首位或者第二位,右边的基准值处于数组的末位或末尾的前一位


 算法描述:

       设置两个变量 start、end,排序开始时:通过调用函数传参,start = 0,end = size-1。
1. 在整个数组找到基准值的位置,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面
        默认数组的第一个数为基准数据,赋值给norm,即norm=arr[start]。
        因为默认数组的第一个数为基准,所以从后面开始向前搜索(end--),找到第一个小于norm的arr[end],就将 array[end] 赋给 array[strat],(循环条件是 array[end] >= norm)
        此时再从前面开始向后搜索(start++),找到第一个大于norm的array[start],就array[start] 赋给 array[end],(循环条件是 array[start] <= norm)

        循环执行此步骤,直到 start=end,该位置就是基准位置。此时把基准数据赋给当前位置。

2.第一次循环找到的基准位置,分别用作为下一趟的分界点,start-1 和 start+1;

3.递归调用分界点前和分界点后的子数组排序,重复第一步;

4.最终就会得到排序好的数组。


动图演示:



代码实现:

#include <stdio.h>
#define N 10

/*
快排函数
	整体思想,每次都取最左边的数据作为基准值,循环一次后,
将基准值放入中间位,即 i == j的位置。
	此时,基准值在中间,左边都是比基准小的数,右边都是比基准大的数,
之后分别让基准值左边的数据和右边的数据继续执行快速排序,
直到最后i-1 < start, i+1 > end,
即左边基准值处于数组首位或者第二位,右边的基准值处于数组的末位或末尾的前一位
*/
void Qucick_sort(int *arr, int start ,int end) {
	int i = start; //i指向数组首位
	int j = end; //j指向数组末位
	int norm = arr[i]; //设置一个基准值,每次都取数组首位作为基准值
	while(i < j) { 	//进行第一轮排序,停止的条件是i == j  
		while(i < j && norm <= arr[j]) { 	//拿基准值与末位和其之前的数据循环比较
			j--;
		}
		arr[i] = arr[j]; 	//如果有比基准值小的值,跳出循环,进行数据交换
		//再将基准值与左边的数据进行比较
		while(i < j && norm >= arr[i]) {
			i++;
		}
		arr[j] = arr[i];
	}
	//第一次循环执行完毕后,将基准值放入中间位,即 i == j的位置
	arr[i] = norm;
	//比较第一次基准值左边的所有数据,递归执行快排函数即可
	if(i-1 > start) {
		Qucick_sort(arr,start,i-1);
	}
	//比较第一次基准值右边的所有数据,递归执行快排函数即可
	if(i+1 < end) {
		Qucick_sort(arr,i+1,end);
	}
	return;
}

int main(int argc, const char *argv[])
{
	
	int arr[N] = {55, 24, 45, 15, 96, 23, 36, 76, 36, 0};
	int i;
	
	printf("排序前\n");
	for(i = 0;i < sizeof(arr)/sizeof(arr[0]);i++) {
		printf("%d ",arr[i]);
	}
	putchar(10);
	//调用快速排序函数,传递想要排序的数组和起始下标
	Qucick_sort(arr, 0, N-1);//数组最后一位的下标是 N-1

	printf("排序后\n");
	for(i = 0;i < sizeof(arr)/sizeof(arr[0]);i++) {
		printf("%d ",arr[i]);
	}
	putchar(10);

	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值