算法导论:期望为线性时间的选择算法

在这里插入图片描述

 在这里插入图片描述

 

/*
	p:期望为线性时间的选择算法
	t:2018年5月2日 11:06:05

*/
#include<iostream>
#include<stdio.h>
//随机数
#include<stdlib.h>
#include<time.h>

using namespace std;

//随机化找出第i小的数
/*
   a[] 数组名
   p 起始位置
   r  结束位置
   i     第i小的数
*/
//划分程序
int Randomized_Partition(int a[], int p, int r);
//循环版本
int Randomized_Seletct(int a[], int p, int r, int i)
{

	//划分数组
	int q = Randomized_Partition(a, p, r);


	while (p != r)
	{
		if (q == i)
		{
			return a[q];
		}
		else if (i < q)//主元的前半部分
		{
			r = q - 1;
			q = Randomized_Partition(a, p, r);
		}
		else//主元的后半部
		{
			p = q + 1;
			q = Randomized_Partition(a, p, r);
		}
	}

	return a[p];

}





int Randomized_Seletct1(int a[], int p, int r, int i)
{
	//只有一个数
	if (p == r)
	{
		return a[p];
	}

	//划分数组
	int q = Randomized_Partition(a, p, r);

	//主元到数组开始元素的个数
	int k = q - p +1;

	//这里用 k == i比较,而不用  q == i比较,因为i是一直变化的
	if (k == i)
	{
		return a[q];
	}
	else if ( i <  k)//主元的前半部分
	{
		return Randomized_Seletct1(a, p, q - 1, i);
	}
	else//主元的后半部
	{
		return Randomized_Seletct1(a, q+1, r, i-k);//
	}
	
}

//划分程序
int random(int min, int max);
//交换两数的值
void exchange(int &a, int &b);

int Randomized_Partition(int a[], int begin, int end)
{

	//随机化
	int  r = random(begin, end);
	int tmp = a[r];
	a[r] = a[end];
	a[end] = tmp;


	//
	int x = a[end];//比较的对象是最后一个元素
	int i = begin - 1;//i是比x小的元素的最后一个位置
	
	for (int j = begin; j < end; ++j)
	{
		if (a[j] < x)
		{
			i++;

			exchange(a[i], a[j]);			
		}	
	}

	exchange(a[end], a[i + 1]);

	return i + 1;
}


//随机数产生 [min,max]
int random(int min, int max)
{
	srand(time(0));

	return rand() % (max - min +1 ) + min;
}
//交换
void exchange(int &a, int &b)
{
	if (a != b)
	{
		int tmp = a;
		a = b;
		b = tmp;
	}
}



int main()
{
	//第一个位置不用,999999为垃圾值
	int a[] = {  999999,0,1,3 ,5,7,9,8,6,4,2};
	int len = sizeof(a) / sizeof(int);

	for (int i = 1; i <len; ++i)
	{
		int num = Randomized_Seletct(a, 1, len-1 , i);

		printf("第%d小的数是:%d\n", i, num);
	}
	for (int i = 1; i <len; ++i)
	{
		int num = Randomized_Seletct1(a, 1, len - 1, i);

		printf("第%d小的数是:%d\n", i, num);
	}


	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值