选择问题 -线性时间选择

选择问题 -线性时间选择

问题描述:
元素选择问题:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素。
线性时间选择算法:
模仿快速排序算法,
首先对输入数组进行划分,
然后对划分出的子数组之一进行递归处理。
对于给定的n个元素的数组a[0:n—1],要求从中找出第k小的元素。
输入;输入有多组测试例。
对每一个测试例有2行,第一行是整数n和k(1≤k<n≤1000),第二行是n个整数。
在这里插入图片描述
快速排序的基本思想:
首先选第一个数作为分界数据,
将比它小的数据存储在它的左边,比它大的数据存储在它的右边,它存储在左、右两个子集之间。
这样左、右子集就是原问题分解后的独立子问题。
再用同样的方法,继续解决这些子问题,直到每个子集只有一个数据,就完成了全部数据的排序工作。`在这里

//选择问题
//采用分治策略找出第k小元素的算法
#include<iostream>
#define NUM 1001
using namespace std;

int a[NUM];
int select(int left, int right, int k)
{
	//找到了第k小的元素
	if (left >= right)
		return a[left];
	int i = left;	//从左向右的指针
	int j = right + 1;	//从右向左的指针

	//把最左边的数据作为分解数据
	int pivot = a[left];

	//把左边大于pivot的元素与右侧小于pivot的元素交换
	while (true)
	{
		//在左侧寻找>=pivot的元素
		do {
			i = i + 1;			//先将指针指向要进行判断的元素,然后再进行判断,如果不满足判断条件,指针将继续指向该元素
		} while (a[i] < pivot);

		//在右侧寻找《=pivot的元素
		do {
			j = j + 1;
		} while (a[j] > pivot);

		if (i >= j)
			break;//没有发现交换对象

		swap(a[i], a[j]);		//如果发现左边的有大于pivot,右边有小于pivot的则将两者进行交换
	}

	if (j - left + 1 == k)
		return pivot;
	a[left] = a[j];
	a[j] = pivot;

	if (j - left + 1 < k)
		return select(j + 1, right, k - j + left - 1);
	else
		return select(left, j - 1, k);
}

int main()
{
	int n,m;
	cin >> n >> m;


	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}

	int j = select(0, n - 1, m);
	cout << a[j];
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值