(求 大哥大姐们帮助)利用分治策略,在n个不同元素中找出第k个最小元素 【 最好有算法】

kwxiang 2008-05-03 02:20:30
把n个元素放在顺序表中,然后取第k个元素作为标准m,把n个元素重新排列,分成两个区间:小于标准m的元素区间1~j,大于标准m的元素区间j+1~n,接下来有三种情况:
1)j=k,则找到第k个元素。
2)j<k,则第k个元素在区间j+1~n。
3)j>k,则第k个元素在区间1~j。
在情况2和3中继续寻找。
...全文
1848 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
kevinlwf 2010-12-14
  • 打赏
  • 举报
回复
貌似这个程序有问题
[Quote=引用 1 楼 baihacker 的回复:]
C/C++ code
#include <stdio.h>
#include <stdlib.h>
int FindMinK(int data[], int l, int r, int k)
{
int m = data[l+k-1], t = 0;
int i, j;
data[l+k-1] = data[r], data[r] = m;
for ……
[/Quote]
jdslfs 2010-11-24
  • 打赏
  • 举报
回复
学习学习 谢谢 哈
kojie_chen 2008-05-06
  • 打赏
  • 举报
回复
同学,呵呵
  • 打赏
  • 举报
回复
貌似二分查找,好久没看数据结构中的算法了,呵呵!忘得差不多了。关注中……
学习了!
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 kwxiang 的回复:]
1楼同学的代码中 i <= sizeof(data)/sizeof(data[0]) 能不能把改成i <=8呢?
[/Quote]
最好用sizeof()是根据系统来定数据大小的,这样,不管是移植到什么系统中,都可以保证其结果的正确性。
glchen57 2008-05-05
  • 打赏
  • 举报
回复
这个问题的解法就是上面有人提到的分区那个算法,也就是快速排序算法的变种。
wlly110 2008-05-05
  • 打赏
  • 举报
回复
学习
baihacker 2008-05-05
  • 打赏
  • 举报
回复
#include <stdio.h> 
#include <stdlib.h>
#define MAXSIZE 100

typedef int datatype;
typedef struct
{
datatype data[MAXSIZE];
int last;
}SeqList;

SeqList *CreatSeqList()
{
SeqList *L;
int temp,i=0;
L=(SeqList *)malloc(sizeof(SeqList));
L->last=-1;
printf("please input the numbers:(End with any character)\n");
while(scanf("%d",&temp))
L->data[i++]=temp;
--i;
L->last=i;
return L;
}

datatype part(SeqList *L,int a,int b,int k)
{
int i,j;
datatype m,t;
datatype* data = L->data;
m=data[a+k-1], data[a+k-1] = data[b],data[b] = m;
for (i=a-1, j = a; j != b; ++j)
if (data[j] < m)
t=data[++i], data[i]=data[j], data[j]=t;
t=data[++i], data[i]=data[j], data[j]=t;
if (k==i-a+1) return m;
if (k>i-a+1) return part(L, i+1, b, k-i+a-1);
else return part(L, a, i-1, k);
}


int main()
{
SeqList *L;
datatype x;
int k,n;
L=CreatSeqList();
n=L->last;
printf("The total number is %d\n",n+1);
printf("Now you can enter number k(1 <=k <=%d):\n",n+1);
fflush(stdin);
scanf("%d",&k);
x=part(L,0,L->last,k);
printf("The %d smallest is %d",k,x);
// getch();
return 0;
}
please input the numbers:(End with any character)
1 3 4 5 7 9
b
The total number is 6
Now you can enter number k(1 <=k <=6):
3
The 3 smallest is 4Press any key to continue
kwxiang 2008-05-05
  • 打赏
  • 举报
回复
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100

typedef int datatype;
typedef struct
{
datatype data[MAXSIZE];
int last;
}SeqList;

SeqList *CreatSeqList()
{
SeqList *L;
int temp,i=0;
L=(SeqList *)malloc(sizeof(SeqList));
L->last=-1;
printf("please input the numbers:(End with any character)\n");
while(scanf("%d",&temp))
L->data[i++]=temp;
--i;
L->last=i;
return L;
}

datatype part(SeqList *L,int a,int b,int k)
{
int i,j,count;
datatype m,n,x;
m=L->data[k-1];
for(i=a;i<=b;i++)
if(L->data[i]<m)
{
n=L->data[i];
for(j=i-1;j>=a;j--)
L->data[j+1]=L->data[j];
L->data[0]=n;
}
count=0;
if(m!=L->data[
if(count==k-1)
{
x=L->data[k-1];
return x;
}
if(count<k-1)
part(L,count+1,b,k);
else
part(L,a,count,k);
}




main()
{
SeqList *L;
datatype x;
int k,n;
L=CreatSeqList();
n=L->last;
printf("The total number is %d\n",n+1);
printf("Now you can enter number k(1<=k<=%d):\n",n+1);
scanf("%d",&k);
x=part(L,0,L->last,k);
printf("The %d smallest is %d",k,x);
getch();
}



这是我写的程序 不知道哪错了 能不能帮我改改 啊?
kwxiang 2008-05-05
  • 打赏
  • 举报
回复
1楼同学的代码中 i <= sizeof(data)/sizeof(data[0]) 能不能把改成i<=8呢?
fengalon_software 2008-05-04
  • 打赏
  • 举报
回复
[Quote=引用楼主 kwxiang 的帖子:]
把n个元素放在顺序表中,然后取第k个元素作为标准m,把n个元素重新排列,分成两个区间:小于标准m的元素区间1~j,大于标准m的元素区间j+1~n,接下来有三种情况:
1)j=k,则找到第k个元素。
2)j <k,则第k个元素在区间j+1~n。
3)j>k,则第k个元素在区间1~j。
在情况2和3中继续寻找。
[/Quote]
在顺序表中,这个方法的确是最好的。
我说说大概,你可以做做
声明3个变量
int max = 99;
int min = 0;
int mid;

定义个数组a[100]
mid = (max+min)/2;

定义个整型变量,你所需要找的数字
int source;

循环找到:
while()
{
if(source == a[mid])
{
printf(mid);
break;
}
else if(source < a[mid])
{
max = mid;
mid = (max+min)/2;
}
else
{
min = mid;
mid = (max+min)/2;
}
}
思想就如上面。
WingForce 2008-05-04
  • 打赏
  • 举报
回复
STL的nth_element的实现:

template<typename _RandomAccessIterator>
void
nth_element(_RandomAccessIterator __first,
_RandomAccessIterator __nth,
_RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;

while (__last - __first > 3)
{
_RandomAccessIterator __cut =
std::__unguarded_partition(__first, __last,
_ValueType(std::__median(*__first,
*(__first
+ (__last
- __first)
/ 2),
*(__last
- 1))));
if (__cut <= __nth)
__first = __cut;
else
__last = __cut;
}
std::__insertion_sort(__first, __last);
}

template<typename _RandomAccessIterator>
void
__insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last)
{
if (__first == __last)
return;

for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
{
typename iterator_traits<_RandomAccessIterator>::value_type
__val = *__i;
if (__val < *__first)
{
std::copy_backward(__first, __i, __i + 1);
*__first = __val;
}
else
std::__unguarded_linear_insert(__i, __val);
}
}
kwxiang 2008-05-04
  • 打赏
  • 举报
回复
所谓快速选择。。。
1、从n个元素中任意选择一个元素a
2、遍历n个元素,将它们分为大于k和小于k的2部分
3、如果小于a的元素数量为k-1个,则a就是解
4、如果小于a的元素数量大于等于k,则递归的对小于a的元素执行快速选择
5、如果小于a的元素数量小于k-1,设大于a的元素有nr个,则递归的对这nr个元素执行快速选择,但是修改求解的目标为k - (n - nr)

注:第1步选择元素a的算法一般为取n个元素的第一个,中间的和尾部的3元素中间的那个。
ll268862 2008-05-03
  • 打赏
  • 举报
回复
学习学习
hnjd314053754 2008-05-03
  • 打赏
  • 举报
回复
学习学习
WingForce 2008-05-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 laolaoliu2002 的回复:]
c语言库函数中已经有bsearch()
[/Quote]
貌似lz要的不是2分查找。。。
laolaoliu2002 2008-05-03
  • 打赏
  • 举报
回复
c语言库函数中已经有bsearch()
baihacker 2008-05-03
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
int FindMinK(int data[], int l, int r, int k)
{
int m = data[l+k-1], t = 0;
int i, j;
data[l+k-1] = data[r], data[r] = m;
for (i = l-1, j = l; j != r; ++j)
if (data[j]<m)
t=data[++i], data[i]=data[j], data[j]=t;
t=data[++i], data[i]=data[j], data[j]=t;
if (k==i-l+1) return m;
if (k>i-l+1) return FindMinK(data, i+1, r, k-i+l-1);
else return FindMinK(data, l, i-1, k);
}
int main()
{
int data[]={8,6,6,4,4,3,2,1};
for (int i = 1; i <= sizeof(data)/sizeof(data[0]); ++i)
printf("%d\n", FindMinK(data, 0, 7, i));
return 0;
}

69,370

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧