【算法导论】线性时间选择---从数组中选择第i小的数

问题:从数组中选择第i小的数,并且要求问题的时间复杂度为O(n)。

代码用到了随机化的快速排序中的分组方法。

其基本原理为:用快速排序的分组方法,随机的选择一个数组元素,使其大于左边的元素,小于右边的元素。然后,看这个元素的下表与要求元素中第i小的值是否相等,如果小于i则表示要查找的元素在当前分组元素的右边,如果大于i表示在左边。这样递归进行,可以达到很高的运行效率。

c++实现的代码如下:

#include <iostream>  
#include <ctime>
#include <set>  
#include <string>  
void swap(int * a,int * b);  
int partition(int * array_list,int left,int right);  
void Print();  
int random_partition(int * array_list,int left,int right);  
const int size = 8;    
int random_slelect(int * array_list,int left,int right,int index);
int * array_list;  
int main()  
{  
	  
	array_list = new int [sizeof(int)*size];  
	srand((unsigned)time(NULL));
	for(int i=0;i<size;i++)  
	{/*随机的填充数组元素*/  
		int ran_num=rand()%( size*10);  
		array_list[i] = ran_num;  
	}  
	Print();  
	std::cout<<random_slelect(array_list,0,size-1,1);
	getchar();
	return 0;  
}  
/*从数组中,选择第i小的数*/
int random_slelect(int * array_list,int left,int right,int index)
{
	int val = 0;
	if(left == right)
	{
		val = array_list[left];
		return val;
	}
	int q = random_partition(array_list,left,right);
	int k = q - left + 1;
	if(index == k)
	{
		return array_list[q];
	}
	else if( index < k)
	{
		random_slelect(array_list,left,q-1,index);
	}
	else
	{
		random_slelect(array_list,q+1,right,index - k);
	}
}

/*随机化的快速排序分组方法,对于输入的元素加入随机化的成分,使之获得较好的平均性能*/  
int random_partition(int * array_list,int left,int right)  
{  
	srand(left);  
	int ran_num=( rand())% right;  
	if((ran_num < left ))  
	{/*防止出现因为取模后随机数为0的情况*/  
		ran_num = left;  
	}  
	/*如果,不交换排序区间内的数据,则成为普通的快速排序*/  
	swap(&array_list[right],&array_list[ran_num]);  
	return partition(array_list,left,right);  
}  
int partition(int * array_list,int left,int right)  
{  
	int index = left;  
	int pivot = array_list[right];  
	for(int i= left ; i< right; i++)  
	{  
		if(array_list[i] < pivot)  
		{  
			swap(&array_list[index],&array_list[i]);  
			index ++;  
		}  
	}  
	swap(&array_list[right],&array_list[index]);  
	//Print();  
	return index;  
}  
void swap(int * a,int * b)  
{  
	int  tmp = *a;  
	*a = *b;  
	*b = tmp;  
}  
void Print()  
{  
	for(int i=0;i< size;i++)  
	{  
		std::cout<<array_list[i]<<"\t";  
	}  
	std::cout<<std::endl;  
}  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值