最坏情况为线性时间的选择算法

本文介绍了一种基于中位数的选择算法实现方法,通过插入排序和递归分区技术找到第i小的元素。该算法首先对数组进行划分并找出中位数的中位数作为枢轴,然后递归地在划分后的子数组中继续查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

按照算法导论(3th 中文)Page123上的步骤、

代码比较乱、

#include <iostream>
using namespace std;
void exchange(int &a, int &b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}
int partition(int A[],int p, int r, int key)
{
	int i = p - 1,j;
	for(j=p;j<r; ++j)
		if(A[j]==key)
			break;
	exchange(A[j],A[r]);
	for(j=p; j<r; ++j)
	{
		if(A[j]<=key){
			i++;
			exchange(A[i],A[j]);
		}
	}
	exchange(A[i+1],A[r]);
	return i+1-(p-1);
}
void insert_sort(int A[],int p, int r)
{
	if(p>=r)
		return;
	int key,i,j;
	for(j=p+1;j<=r; j++)
	{
		key = A[j];i=j-1;
		while(i>=p && A[i]>key)
		{
			A[i+1] = A[i];
			i = i-1;
		}
		A[i+1] = key;
	}
}
int select(int A[],int p, int r, int i)
{
	if(p==r)
		return A[p];
	int k = p+4;
	while(k<=r)
	{
		insert_sort(A, k-4, k);
		k += 5;
	}
	insert_sort(A, k-4, r);
	int num;
	num = (r-p+1)/5 + ( (r-p+1)%5 ? 1:0 );
	int *new_arr = new int[num];
	for(int j=0;j<num-1;++j)
		new_arr[j] = A[3+j*5+p-1];
	//找出最后一个中位数
	k = r-(num-1)*5 - (p - 1);
	if(k%2)k = k + 1;
	k = k/2;
	k += (num-1)*5 + p - 1;
	new_arr[num-1] = A[k];
	//对[n/5]个中位数进行插入排序,找出中位数的中位数x
	insert_sort(new_arr, 0, num-1);
	int x = new_arr[(num-1)/2];
	delete new_arr;
	//按中位数x对输入数组进行划分
	k = partition(A,p,r,x);
	if(k==i)
		return x;
	else if(k>i)
		select( A, p, k-1 + (p-1), i);
	else
		select( A, k+1 + (p-1), r, i-k);
}
void test()
{
	int A[] = {0,50,90,100,70,30,20,40,60,80,10};
	for(int i = 1; i<=10; ++i)
		cout<<select(A,1,10,i)<<" ";
	cout<<endl;
}
int main()
{
	test();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值