算法-快速排序quickSort

最常用的排序–快速排序

以下讲解借鉴了啊哈算法一部分内容,如果有总结不到位的地方,恳请给位大佬批评指正

优点:相比较桶排序和冒泡排序来说,快速排序解决了桶排序的空间的浪费,和冒泡排序的执行效率

示例:

排列前

6	1	2	7	9	3	4	5	10	8

排列后

1	2	3	4	5	6	7	8	9	10
  • 首先,我们先随便找一个数作为 基准数 ,在这里我们选择最左侧的 6 作为基准数。
  • 对于现在我们需要做的就是把 基准数 6 移到之间的某一个位置,这里先提示一下,采用类似于 冒泡算法 (下次进行详解)的交换顺序,当然这里我们并不会对所有的数进行一个比较,而是选择,往下学,自然就懂了。
  • 对序列的两端进行“探测”,定义两个哨兵 一个哨兵i,一个哨兵j,一个在序列的头部,一个在尾部。//也就是双指针
  • 这里我们注意,哨兵j先移动。因为此时设置的的基准数为最左侧的数,所以是哨兵j先进行移动,这一点务必理解。哨兵j一步一步的向左移动(即j–),直到找到小于基准数6的数停下来。接下来的是哨兵i****向右进行移动(即i++),直到找到一个比基准数6大的数停下来。最后哨兵j停在了数字5前面,哨兵i停在了数组7前面。
  • 然后进行一次交换初始序列
    找到满足要求的数字
    进行了第一次数交换
  • 到这里已经进行了一次交换
	6	1	2	5	9	3	4	7	10	8
  • 以上我们已经进行了一次交换,然后再进行上述方法
    交换

交换

  • 第二次交换进行结束,探测继续。哨兵j继续向左移动,他会发现数字3,满足条件之后停下来,哨兵i向右移动,然后和哨兵相遇。说明在此时,探测已经结束了。然后数字3基准数6进行交换
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
 3	1	2	5	4	6	9	7	10	8

到了此时,第一次探测已经结束
对刚刚的探测进行一次回顾:

  1. 此时以基准数6为分界线,6左边的为小于等于6的数字
  2. 6右边的数都大于等于6
  3. 哨兵j找到小于基准数的数
  4. 哨兵i找到大于基准数的数
  5. 直到哨兵i和哨兵j碰头为止

现在基准数已经归位了,现在我们将初始序列拆分成以原基准数为界线的两个序列

左边为

3	1	2	5	4

右边为

9	7	10	8

现在你可以试一试自己找一下基准数然后在画板上进行一次演练

对于左边选择3为基准数进行探测
交换后得到

2	1	3	5	4

以此类推
再分隔为左侧

2	1	

右侧

5	4	

交换后可得

1	2	3	4	5	6	9	7	10	8

对于初始基准数的右边可以分隔为

9	7	10	8

这里基准数选9
探测结束后可以得到

8	7	9	10

然后继续探测
左侧(右侧就一个10,没有必要进行分隔)

8	7	

ok最后了,进排序可得

7	8

终于卸下一口气
全部排序完了

1	2	3	4	5	6	7	8	9	10

等你以上全部看懂后你可以自行写出图解,当然我这里也准备好了
在这里插入图片描述

以上就是快速排序的一个思想,以下就是代码演示

#include<stdio.h> 

int a[101],n;//定义全局变量,这两个变量需在子函数中使用 

void quicksort(int left, int right){
	int i,j,t,temp;
	if(left > right)
		return;
	temp = a[left];//temp中存储基准数
	
	i = left;
	j = right;
	
	while(i != j){
		//顺序很重要,要先从右往左找 
		while(a[j] >= temp && i < j)
			j--;
		
		//再从左往右找 
		while(a[i] <= temp && i < j)
			i++;
		
		//交换两个数在数组中的位置
		if(i < j){
			t = a[i];
			a[i] = a[j];
			a[j] = t;
		} 
		
	} 
	
	//最终将基准数归位 
	a[left] = a[i];
	a[i] = temp;
	
	quicksort(left, i - 1);//继续处理左边,这里是一个递归的过程
	quicksort(i + 1, right);
	return; 
} 

int main(){
	int i, j;
	//读入数据
	printf("输入需要排序的数字元素数量:\n");
	scanf("%d",&n);
	printf("输入需要排序的数字元素量:\n");
	for(i = 1;i <= n; i++)
		scanf("%d",&a[i]);
		
	quicksort(1, n);//快速排序调用
	
	//输出排序后的结果
	for(i = 1; i <= n; i++){
		printf("%d\t",a[i]);
	} 
	
	return 0;
}

注意:

  1. 快速排序的最差时间复杂度和冒泡排序相同都是O(N^2)
  2. 但是平均的时间复杂度为O(NlongN)
  3. 基于二分思想实现
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
快速排序QuickSort)是一种高效的排序算法,它的平均时间复杂度为O(nlogn)。它是通过将待排序数组分成两部分,其中一部分的所有元素都比另一部分的所有元素小,然后对这两部分分别进行递归排序,最终将整个数组排序。 以下是Java实现的快速排序代码: ```java public class QuickSort { public static void quickSort(int[] arr, int start, int end) { if (start < end) { int pivot = partition(arr, start, end); quickSort(arr, start, pivot - 1); quickSort(arr, pivot + 1, end); } } private static int partition(int[] arr, int start, int end) { int pivot = arr[end]; int i = start - 1; for (int j = start; j < end; j++) { if (arr[j] <= pivot) { i++; swap(arr, i, j); } } swap(arr, i + 1, end); return i + 1; } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static void main(String[] args) { int[] arr = {5, 3, 8, 4, 2, 7, 1, 10}; quickSort(arr, 0, arr.length - 1); for (int i : arr) { System.out.print(i + " "); } } } ``` 在这个实现中,我们使用了递归来进行快速排序。首先,我们将数组分成两部分,然后对这两部分分别进行递归排序。在partition函数中,我们选择了数组的最后一个元素作为枢轴(pivot),并通过比较其他元素和枢轴的大小进行交换,将比枢轴小的元素放在枢轴的左边,比枢轴大的元素放在枢轴的右边。最后,我们将枢轴放在数组的正确位置上,并返回该位置。 在这个实现中,我们使用了swap函数来交换数组中的元素。我们也可以使用Java自带的Arrays.sort()函数来进行快速排序,它的实现也是基于快速排序算法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊猫写算法er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值