分治法求第k大元素c语言,分治法求第K大元素2

#include

#include

using namespace std;

/***************************************

* 选择第k小元素算法

*

* 输入:元素数组A[],元素个数n,求的k

* 输出:第k小元素

***************************************/

template

Type select(Type A[], int n, int k){

int i, j, s, t;

Type m, *p, *q, *r;

if (n<38){ // 如果元素个数小于38:则直接排序

sort(A, A + n);

return A[k - 1];

}

p = new Type[3 * n / 4];

q = new Type[3 * n / 4];

r = new Type[3 * n / 4];

for (i = 0; i

mid(A, i, p);

}

m = select(p, i, i / 2 + i % 2); // 递归调用,取得中值元素存入m

i = j = s = 0;

for (t = 0; tm把数组分成三组

{

if (A[t]

p[i++] = A[t];

}

else{

if (A[t] == m){

q[j++] = A[t];

}

else{

r[s++] = A[t];

}

}

}

if (i>k){ // 若k

return select(p, i, k);

}

else{

if (i + j >= k){ // 若i

return m;

}

else{ // 若k>i+j,则该元素在r数组中,进入r继续寻找

return select(r, s, k - i - j);

}

}

}

/***************************************

* 计算中值元素

*

* 输入:元素数组A[],组号i

* 输出:存放中值元素的数组p[]

***************************************/

template

void mid(Type A[], int i, Type p[]){

int k = 5 * i;

if (A[k]>A[k + 2]){

swap(A[k], A[k + 2]);

}

if (A[k + 1]>A[k + 3]){

swap(A[k + 1], A[k + 3]);

}

if (A[k]>A[k + 1]){

swap(A[k], A[k + 1]);

}

if (A[k + 2]>A[k + 3]){

swap(A[k + 2], A[k + 3]);

}

if (A[k + 1]>A[k + 2]){

swap(A[k + 1], A[k + 2]);

}

if (A[k + 4]>A[k + 2]){

p[i] = A[k + 2];

}

else{

if (A[k + 4]>A[k + 1]){

p[i] = A[k + 4];

}

else{

p[i] = A[k + 1];

}

}

}

int main()

{

int n, m;

int x, y;

int k1, k2;

cout << "请输入数组元素个数:";

cin >> n;

cout << "请输入要求的k1,k2:";

cin >> k1;

cin >> k2;

int *A = new int[n];

int i;

cout << "请输入数组元素:" << endl;

for (i = 0; i

cin >> A[i];

}

x = select(A, n, n - k1 + 1);

y = select(A, n, n - k2 + 1);

//cout << "第" << m << "大元素是:";

//cout << select(A, n, n - m + 1) << endl; // 输出第(n-m+1)小元素<=>第m大元素

//获取数组下标方式

for (int i = 0; i < n;i++)

{

if (A[i] == x || A[i] == y)

{

k1 = i;

break;

}

}

for (int i = n; i > 0; i--)

{

if (A[i] == x || A[i] == y)

{

k2 = i;

break;

}

}

for (; k1 <= k2;k1++)

{

cout << A[k1] <

}

system("pause");

return 0;

}

#include

using namespace std;

#define max 100

typedef struct Data

{

int data;

bool flag;

}Data, Mat[max];

Mat a;

void Found_k1_k2(Mat &a, int n, int k1, int k2)//用减治法查找无序列表中第k1到第k2小的整数

{

int x = 0;

int y = n - 1;

while (xk2 - 1)

{

int temp;

int f1, f2;//存储最小和最大数的下标

f1 = x;

f2 = y;

for (int i = x; i <= y; i++)

{

if (a[f1].data > a[i].data)

f1 = i; if (a[f2].data < a[i].data)

f2 = i;

}

if (x < k1 - 1)

{

temp = a[x].data;

a[x].data = a[f1].data;

a[f1].data = temp;

a[x].flag = 0;

x++;

}

if (y > k2 - 1)

{

temp = a[y].data;

a[y].data = a[f2].data;

a[f2].data = temp;

a[y].flag = 0;

y--;

}

}

}

void Show(Mat &a, int n, int k1, int k2)

{

cout << "第" << k1 << "小到" << k2 << "小之间的所有整数有:";

for (int i = 0; i < n; i++)

{

if (a[i].flag)

cout << a[i].data << " ";

}

cout << endl;

}

void main()

{

int choice;

cout << " 1: 执行程序 2: 退出程序" << endl;

do

{

cout << "请选择你的操作:";

cin >> choice;

switch (choice)

{

case 1:

{ int n;

int k1, k2;

cout << "请输入无序列表n的大小:";

cin >> n;

cout << "请输入无序列表中的所有整数:";

for (int i = 0; i < n; i++)

{

a[i].flag = 1;

cin >> a[i].data;

}

cout << "请输入k1k2的值:";

cin >> k1 >> k2;

if (k1 > k2)

{

int temp = k1;

k1 = k2;

k2 = temp;

}

if (k1<0 || k2>n || n < 0)

{

cout << "输入不和法!!请重新输入!!" << endl;

break;

}

Found_k1_k2(a, n, k1, k2);

Show(a, n, k1, k2);

break;

}

case 2:

{

cout << "退出程序";

break;

}

default:cout << "选择不合理请重选" << endl;

}

}

while (choice != 2);

}

#include

using namespace std;

#define swap(x, y) {int a = x; x = y; y = a;}

#define max 100

typedef struct Data

{

int data;

bool flag;

}Data, Min[max];

Min a;

void Binary_search(Min &a, int n, int k1, int k2)

{

//用减治法查找无序列表中第k1到第k2小的整数

int x = 0;

int y = n - 1;

while (x < k1 - 1 || y > k2 - 1)

{

int temp;

//存储最小和最大数的下标

int f1, f2;

f1 = x;

f2 = y;

for (int i = x; i <= y; i++)

{

if (a[f1].data > a[i].data)

f1 = i; //缩小空间

if (a[f2].data < a[i].data)

f2 = i;

}

//下面两段if相当于把不在k1,k2范围内的数组元素统统删掉

if (x < k1 - 1)

{

temp = a[x].data;

a[x].data = a[f1].data;

a[f1].data = temp;

a[x].flag = 0;

x++;

}

if (y > k2 - 1)

{

temp = a[y].data;

a[y].data = a[f2].data;

a[f2].data = temp;

a[y].flag = 0;

y--;

}

}

cout << "第" << k1 << "小到" << k2 << "小之间的所有整数有:";

for (int i = 0; i < n; i++)

{

if (a[i].flag)

cout << a[i].data << " ";

}

cout << endl;

}

void main()

{

int n;

int k1, k2;

cout << "请输入无序列表大小::";

cin >> n;

cout << "请输入无序列表中元素:";

for (int i = 0; i < n; i++)

{

a[i].flag = 1;

cin >> a[i].data;

}

cout << "请输入k1k2的值:";

cin >> k1 >> k2;

if (k1 > k2)

swap(k1, k2);

if (k1<0 || k2>n || n < 0)

{

cout << "输入不合法!" << endl;

}

Binary_search(a, n, k1, k2);

system("pause");

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值