选择算法(基于快速排序修改):选择第i小的值

1、选择最大最小值:
a)选择最大或最小值,可以遍历数组所有元素,在线性时间O(n)内完成。
代码:

int findmax(int* A,int N)
{
	int max = A[0];
	int tmp;
	for(int i = 1;i<N;i++){
		tmp = A[i];
		if(tmp>max){ max = tmp; }
	}
	return max;
}

b) 同时选出最大和最小值
分析:独立找最大和最小值,时间复杂度为O(2(n-1))
因此改为,将一对输入数据进行比较,较小的于当前最小值比较,较大的与当前最大值比较。所以4个元素比较3次,时间复杂度为O(3[n/2])
在这里插入图片描述
伪代码:

int findmax(int* A,int N)
{
	int max,min; 
	if(n%2 == 0) { //n为偶数
		if(A[0]>A[1]) {max =A[0]; min =A[1];}
		else { max =A[1]; min =A[0]; }
	}
	else{
		max =min =A[0];
	}
	int tmp1,tmp2; //同时比较两个数
	。。。
	return max, min;
}

2、选择算法:返回数组A[p…r]中第i小的元素
思路:分治思路,快速排序的修改,时间复杂度为O(n)
与快速排序一样,仍然将输入数据进行递归划分。但快速排序对两边都进行继续递归,因此时间复杂度为O(nlgn),但选择算法只对一边进行递归,时间复杂度为O(n)。
代码(假设各元素互异):

int SelectK(int *A, int l, int r, int k);//找第k小数
{
	if(l == r) return A[l];
	int pivot = Partition(A, l, r); //返回主元的下标
	if(pivot == k-1) return A[pivot]; // 主元的下标为k-1则返回(下标从0开始,所以-1)
	else if(pivot >k-1) return SelectK(A, l, pivot-1, k); // 若下标大则在左边递归
	else return SelectK(A, pivot+1, r, k-pivor-2); // 小则在右边递归
}

int Partition(int *A, int l, int r)
{
	int pivot = A[r]; //将数组最后一个值作为主元
	int i = l;
	int j = r-1;
	for(;;){
		while (A[i]<pivot){i++;}
		while (A[j]>pivot){j--;}
		if(i<j) swap(A[i],A[j]);
		else break;
	}
	swap(A[i],A[right]); //将主元放在中间位置
	return i;
}

注:数组最后一个值作为主元,利用主元所在下标表示元素个数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值