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);
}