分治算法求数组第k小元素

1.问题

在 数组S中查找第k小的元素并输出(分治算法)

2.解析

将S分为多个组q,每组5个元素,有剩余的话,则排序剩余元素。 将q个组单独排序,每组找出中项,中项组成集合M,以M中项n作为标准,将S划分为两个子数组S1和S2,把这个数组中比n小的都放入S1的数组中,数组S1的元素个数是|S1|个;把这个数组中比n大的都放入S2的数组中,数组S2的元素个数是|S2|个。
当要找的k<|S1|,就S1中找第k小的子问题。
当要找的k=|S1|+1, n=k。
当要找的k>|S1|+1,就在数组S2中找第k小的子问题。

3.设计

int Select(int *in,int L,int H, int s) {

	int m = H+ 1 - L ;int n = m / 5;
int * mo = (int*)malloc(sizeof(int) * n);
if (m < max) {
	sort(in, L, H);// 进行排序
	return in[L + s];
}

 
for (int i = 0; i < n; i++) {
	sort(in, L + 5 * i, L + 5 * i + 4);
	mo[i] = in[L + 5 * i + 2];
}
int t1 = 0,t2 = 0,t3 = 0;
    int mid = Select(mo, 0, n, (n - 1) / 2), * a = (int*)malloc(sizeof(int) * m);
    int * b = (int*)malloc(sizeof(int) * m);
 int * c = (int*)malloc(sizeof(int) * m);

for (int i = L; i <= H; i++) {
	
	if (in[i] = mid)
		 b[t2++] = in[i];
	else if (in[i] > mid) 
		c[t3++] = in[i];
	else  
		 a[t1++] = in[i];
}
if(t1 + t2 >= s)
  	return mid;
else if   (t1 > s) 
	return Select(a, 0, t1 - 1, s);
else 
	return Select(c, 0, t3 - 1, s - t1 - t2);

}

4.分析

最坏情况:
T(n)=O(n^2 )
一般情况:
T(n)=T(n/2)+n-1
T(n)=O(n)

5.源码

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define max 44

int sort( int *in,int L, int H);
int Select(int *in,int L,int H, int s);

int main() {
int n;
scanf("%d", &n);

int * in = (int*)malloc(sizeof(int) * n);
 
for (int i = 0; i < n; i++) {
	scanf("%d", &in[i]);
}
int k  ;
scanf("%d",&k);
printf("第k小素是:%d\n",Select(in, 0, n - 1, k-1));

return 0;

}

int sort( int *in,int L, int H) {
for (int i = L; i <= H; i++) {
for (int j = L; j <= H - L - 1; j++) {
int temp;
if (in[j] >in[j + 1]) {
temp = in[j + 1];
in[j + 1]=in[j] ;
in[j]=temp;
}

	}
}

}
int Select(int *in,int L,int H, int s) {

	int m = H+ 1 - L ;int n = m / 5;
int * mo = (int*)malloc(sizeof(int) * n);
if (m < max) {
	sort(in, L, H);
	return in[L + s];
}

 
for (int i = 0; i < n; i++) {
	sort(in, L + 5 * i, L + 5 * i + 4);
	mo[i] = in[L + 5 * i + 2];
}
int t1 = 0,t2 = 0,t3 = 0;
    int mid = Select(mo, 0, n, (n - 1) / 2), * a = (int*)malloc(sizeof(int) * m);
    int * b = (int*)malloc(sizeof(int) * m);
 int * c = (int*)malloc(sizeof(int) * m);

for (int i = L; i <= H; i++) {
	
	if (in[i] = mid)
		 b[t2++] = in[i];
	else if (in[i] > mid) 
		c[t3++] = in[i];
	else  
		 a[t1++] = in[i];
}
if(t1 + t2 >= s)
  	return mid;
else if   (t1 > s) 
	return Select(a, 0, t1 - 1, s);
else 
	return Select(c, 0, t3 - 1, s - t1 - t2);

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值