实验内容:
1、给定线形序列集中n个元素和一个整数k,1≤k≤n,输出这n个元素中第k小元素的值及其位置;
2、简述该算法的原理、步骤。对该算法与直接排序查找进行比较;
3、编写并调试程序。
测试要求:元素个数不少于100
// SelectK.cpp : 分治法选择第k 小的元素。
// VC++6.0 下测试通过
#include <iostream.h>
#include <stdlib.h>
#include <time.h>
// 交换两个变量的值
void Swap(int& a, int& b)
{
int t = a;
a = b;
b = t;
}
// 在a [ l : r ]中选择第k小的元素
int Select(int a[], int l, int r, int k)
{
if (l >= r) return a[l];
int i = l, // 从左至右的游标
j = r + 1; // 从右到左的游标
int pivot = a[l];
// 把左侧>= pivot的元素与右侧<= pivot 的元素进行交换
while (true) {
do {// 在左侧寻找>= pivot 的元素
i = i + 1;
} while (a[i] < pivot);
do {// 在右侧寻找<= pivot 的元素
j = j - 1;
} while (a[j] > pivot);
if (i >= j) break; // 未发现交换对象
Swap(a[i], a[j]);
}
if (j - l + 1 == k) return pivot;
// 设置pivot
a[l] = a[j];
a[j] = pivot;
// 对一个段进行递归调用
if (j - l + 1 < k)
return Select(a, j+1, r, k-j+l-1);
else
return Select(a, l, j-1, k);
}
// 打印数组时,每行的数字个数。
const int NumbersPerLine = 15;
// 打印数组数据到屏幕
void Print(int a[], int n)
{
for(int i = 0; i < n; ++i)
{
cout<}
// 主函数,程序入口点
void main()
{
int n; // 元素的总个数
int k; // 第k小
InputN:
cout<<"请输入元素的个数n=";
cin>>n;
if(n < 1)
{
cout<<" 错误:n值输入错误,请重新输入!nn";
goto InputN;
}
InputK:
cout<<"请输入k,范围为1~"<
goto InputK;
}
// 随机生成n个元素
int * a = new int [n];
srand( (unsigned)time( NULL ) );
int bound = n * 10; // 最大值为n的10倍。
for(int i = 0; i < n; ++ i)
{
a[i] = rand() % bound + 1;
}
// 显示生成的数据
cout<
cout<<"随机生成的"<
Print(a,n);
// 计算结果
cout<
cout<<"第"<
cout<
// 释放数据内存
delete [] a;
}