快排算法,以及 top_k应用

快速排序 的思想是 以最左边的数值为基准,将它放在一个位置,使左边的数都比它小,右边的数都比它大,然后递归

举个例子来说:

4,2,1,5,7,8,2,3,7  这9个数

首先sort(0,8)  以最左边a[0]=4为基准,经过一系列调整过程 变成这样 3 2 1 2 4 8 7 5 7,4现在的位置是4,而且左边都比它小,右边都比它大,然后我们递归sort(0,3) sort(5,8),这样一步一步将问题化小,求出结果


调整过程可以这样做:

前后两个指针,以 sort(0,8) 为例

1. 在后面找到一个比4小的数,交换位置并修改当前位置

数组变成这样 3,2,1,5,7,8,2,4,7

2.在前面找到一个比4大的数,交换位置并修改当前位置

数组变成这样 3,2,1,4,7,8,2,5,7

3.重复第一步

可以在纸上模拟一下~


代码为:

# include <stdio.h>
void swap(int *a,int i,int j){
	int t = a[i];
	a[i] = a[j];
	a[j] = t;
}
int sort(int *a,int l,int r){
	int s,t,cur;
	s = l+1;
	t = r;
	cur = l;
	while(t > s){
		while(a[t] >= a[cur] && t>s){
			t--;
		}
		swap(a,cur,t);
		cur = t;
		while(a[s] <= a[cur] && t>s){
			s++;
		}
		swap(a,cur,s);
		cur = s;
	}
	for(int i=0; i<=8; i++) printf("%d ",a[i]); printf("\n");
	return cur;
}

void quick_sort(int *a,int l,int r){
	if(l >= r) return;
	int pos = sort(a,l,r);
	quick_sort(a,l,pos-1);
	quick_sort(a,pos+1,r);
}
void top_k(int *a,int l,int r,int sort_l,int sort_r){
	if(l >= r) return;
	int pos = sort(a,l,r);
	if(pos-1 >= sort_r) {
		top_k(a,l,pos-1,sort_l,sort_r);
	} else if(pos+1 <= sort_l){
		top_k(a,pos+1,r,sort_l,sort_r);
	} else{
		top_k(a,l,pos-1,l,pos-1);
		top_k(a,pos+1,r,pos+1,r);
	}

}

int main(){
	int a[]={4,2,1,5,7,8,2,3,7};
	quick_sort(a,0,8);
	//top_k(a,0,8,0,4);
	for(int i=0; i<=8; i++) printf("%d ",a[i]); printf("\n");
}


快速排序有个应用,求数组中最大的k个数

对应的就是代码中的top_k 函数,其实和 quick_sort 函数相差不大,只是加上判断条件,举个例子来说

如果我们想求前4大的数,那么 我们在第一次快排的时候 根本不用求 sort(5,8), 只需要sort(0,3)再递归 就能求出结果了

当然了,我们也可以较快速地求出 第k大的数 ,方法是 pos==k 就返回

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值