算法-减治法-求中值和选择问题

35 篇文章 2 订阅

减治法

减治法是一种一般性的算法设计技术,它利用了一个问题给定实例的解和同样问题较小实例的解之间的关系。一旦建立了这样一种关系,我们既可以自顶至下(递归)也可以自底至上地运用它(非递归)。

减治法有3种主要的变种:

  • 减一个常量,常常是减1(例如插入排序)。
  • 减一个常因子,常常是减去因子2(例如折半查找)。
  • 减可变规模(例如欧几里得算法)。

这里用减可变规模算法来求中值问题和选择问题。

选择问题是求n个数的列表中第k小的元素。特别的,当k=1或者k=n,就是求最小最大值的问题。如果k=n/2,则就是中值问题。

按照快速排序的递归方法。如下,中值是第五小的数,也就是下表为5的时候的值。第一轮的是时候,我们以第一个数 为基准,比他小的就移到前面,比他大的就移到后面,如果下表为5就是中值。否则就以改值的下一个为基准继续。第一轮的时候,4是第三小的数,所以对后一部分就行寻找。

下标123456789
序列值411097128215
第一轮214971281015

 

第二轮,9是排在上一轮排完后4后面的一个值,所以以9为基准,进行第二轮过后,9是6小的值,所以对9的前面进行寻找

 

下标123456789
序列值411097128215
第一轮214971281015
第二轮214879121015

第三轮,排完后,得到8是第五小的数,也就是要查找的中值。

下标123456789
序列值411097128215
第一轮214971281015
第二轮214879121015
第三轮214789121015

 

 

#include<iostream>
using namespace std;
#define M 99
int a[M];

void select(int left,int right,int n)
{
	int temp,t;
	int i=left,j=right;
	temp=a[left];
	while(i!=j)
	{
		while(a[j]>temp&&i<j)
			j--;
		if(i<j)
		{
			a[i]=a[j];
			i++;
		}
		while(a[i]<temp&&i<j)
			i++;
		if(i<j)
		{
			a[j]=a[i];
			j--;
		}
	}
	a[i]=temp;
	if(i==n)
		return;  //如果跟需要差找的位数相等就是需要查询的
	else if(i<n)   //如果下于需要查询的位数,则从下一个开始查询
		select(i+1,right,n);
	else    //如果大于查询的位数,则从left开始到right的上一个开始
		select(left,i-1,n);
}
int main()
{
	int n,m;
	cout<<"输入数组大小:";
	cin>>n;
	cout<<"输入数组:"<<endl;
	int temp;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	cout<<"输入选择的数(第几小的数):";
	cin>>m;
	select(1,n,m);   //传入开始的数和结束的数,需要寻找的数  跟快速排序类似
	temp=a[m];
	cout<<"中值是:"<<temp<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值