选择第k小的元素-O(n)的时间复杂度

实现了一下算法书上的例子, 在线性的时间内完成选择第k个元素。

 

  1 /*
  2 
  3  */
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 #include <math.h>
  8 #define MAX 111
  9 
 10 int comp(const void *a, const void *b)
 11 {
 12     int *aa = (int *)a;
 13     int *bb = (int *)b;
 14     return *aa - *bb;
 15 }
 16 
 17 int selection(int *a, int len, int k)
 18 {
 19     int count = len / 5;
 20     int m[MAX], num = 0;
 21     int s1[MAX], s2[MAX];
 22     int num_s1 = 0, num_s2 = 0;
 23     
 24     if (len <= 5)
 25     {
 26         qsort(a, len, sizeof(int), comp);
 27         return a[k - 1];
 28     }
 29     for (int i = 0; i < count; i++)
 30     {
 31         // 5*i to 5*i+4
 32         qsort(a + 5 * i, 5, sizeof(int), comp);
 33         m[num++] = a[5 * i + 2];
 34     }
 35 
 36     int m_star = selection(m, num, num / 2 + 1); // 特别注意如果是num / 2的话,当num=1时,传递给selection的k为0, 导致a[0 - 1]的bug!
 37 
 38     for (int i = 0; i < count; i++)
 39     {
 40         if (a[5 * i + 2] < m_star)
 41         {
 42             s1[num_s1++] = a[5 * i];
 43             s1[num_s1++] = a[5 * i + 1];
 44             s1[num_s1++] = a[5 * i + 2];
 45             
 46             if (a[5 * i + 3] < m_star)
 47                 s1[num_s1++] = a[5 * i + 3];
 48             else
 49                 s2[num_s2++] = a[5 * i + 3];
 50             
 51             if (a[5 * i + 4] < m_star)
 52                 s1[num_s1++] = a[5 * i + 4];
 53             else
 54                 s2[num_s2++] = a[5 * i + 4];
 55         }
 56         else if (a[5 * i + 2] == m_star)
 57         {
 58             s1[num_s1++] = a[5 * i];
 59             s1[num_s1++] = a[5 * i + 1];
 60             s2[num_s2++] = a[5 * i + 3];
 61             s2[num_s2++] = a[5 * i + 4];
 62         }
 63         else
 64         {
 65             s2[num_s2++] = a[5 * i + 3];
 66             s2[num_s2++] = a[5 * i + 4];
 67             s2[num_s2++] = a[5 * i + 2];
 68             
 69             if (a[5 * i] < m_star)
 70                 s1[num_s1++] = a[5 * i];
 71             else
 72                 s2[num_s2++] = a[5 * i];
 73             
 74             if (a[5 * i + 1] < m_star)
 75                 s1[num_s1++] = a[5 * i + 1];
 76             else
 77                 s2[num_s2++] = a[5 * i + 1];
 78         }
 79     }
 80     
 81     for (int i = 5 * count; i < len; i++)
 82     {
 83         if (a[i] < m_star)
 84             s1[num_s1++] = a[i];
 85         else
 86             s2[num_s2++] = a[i];
 87     }
 88     
 89     if (k == num_s1 + 1)
 90         return m_star;
 91     else if (k <= num_s1)
 92         return selection(s1, num_s1, k);
 93     else
 94         return selection(s2, num_s2, k - num_s1 - 1);
 95 }
 96 
 97 int main()
 98 {
 99     int a[] = {9, 8, 10, 1, 1, 1, 1, 20, 11, 11};
100     //int a[] = {19, 20, 15, 9, 10, 11};
101     printf("%d ", selection(a, sizeof(a) / sizeof(int), 6));
102 
103 }

 

posted on 2013-10-01 21:14  leiatpku  阅读(872)  评论(0编辑  收藏  举报