Chinaunix首页 | 论坛 | 博客
  • 博客访问: 505668
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1172
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-21 13:40
个人简介

技术改变命运

文章分类

全部博文(184)

文章存档

2020年(16)

2017年(12)

2016年(156)

我的朋友

分类: C/C++

2016-07-02 21:52:19

选择问题是求一个n个数列表的第k个最小元素的问题。
中位数:百度百科定义如下:
      对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,通常取最中间的两个数值的作为中位数。
中轴p(列表中的第一个元素) Lomuto划分
      考虑一个数组,或者更一般的一个字数组A[l...r](0≤l≤r≤n-1),该数组由连续的3段组成。这3段按顺序排在中轴p的后面:一段为已知小于p的元素,一段为已知大于或等于p的元素,还有一段未同p比较过的元素。这些段可以为空,在算法开始时,前两段通常是空的。
在i= l+1开始,算法从左到右扫面字数组A[l...r],并保持这个结构直到划分完成。在每一次迭代中,它把未知段中的第一个元素与中轴p进行对比。如果A[i] >= p,则只要i+1就扩大了大于等于p元素的段,而同时缩小了未处理的段。  数组中第k小元素的快速选择算法的c代码如下: 

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define swap(t,x,y) (t = (x),x = (y),y = (t))
  4. int lomutoPartition(int *a,int lo,int hi)
  5. {
  6.     int s = lo;
  7.     int i = lo+1;
  8.     int p =a[lo];
  9.     int temp = 0;
  10.     for (i = lo+1;i < hi;i++)
  11.     {
  12.         if (a[i] < p)
  13.         {
  14.             s = s+1;
  15.             swap(temp,a[i],a[s]);
  16.         }
  17.     }
  18.     swap(temp,a[lo],a[s]);
  19.     return s;
  20. }
  21. int quickselect(int *a,int lo,int hi,int k)
  22. {
  23.     
  24.         int s = lomutoPartition(a,lo,hi);
  25.         if (lo+k-1 == k) return a[s];
  26.         else if (lo+k-1 < s) quickselect(a,lo,s-1,k);
  27.         else quickselect(a,s+1,hi,lo+k-s-1);//这里lo别忘记写
  28.     
  29. }
  30. int main()
  31. {
  32.     int a[4] = {1,2,3,4};
  33.     int result = quickselect(a,0,3,2);
  34.     printf("%d\n",result);
  35.     return 0;
  36. }
具体见下一篇文章


阅读(3885) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~