00001 
00011 #include <GKlib.h>
00012 
00013 
00014 #define QSSWAP(a, b, stmp) do { stmp = (a); (a) = (b); (b) = stmp; } while (0)
00015 
00016 
00017 
00019 
00020 int gk_dfkvkselect(size_t n, int topk, gk_fkv_t *cand)
00021 {
00022   int i, j, lo, hi, mid;
00023   gk_fkv_t stmp;
00024   float pivot;
00025 
00026   if (n <= topk)
00027     return n; 
00028 
00029   for (lo=0, hi=n-1; lo < hi;) {
00030     mid = lo + ((hi-lo) >> 1);
00031 
00032     
00033     if (cand[lo].key < cand[mid].key)
00034       mid = lo;
00035     if (cand[hi].key > cand[mid].key)
00036       mid = hi;
00037     else 
00038       goto jump_over;
00039     if (cand[lo].key < cand[mid].key)
00040       mid = lo;
00041 
00042 jump_over:
00043     QSSWAP(cand[mid], cand[hi], stmp);
00044     pivot = cand[hi].key;
00045 
00046     
00047     for (i=lo-1, j=lo; j<hi; j++) {
00048       if (cand[j].key >= pivot) {
00049         i++;
00050         QSSWAP(cand[i], cand[j], stmp);
00051       }
00052     }
00053     i++;
00054     QSSWAP(cand[i], cand[hi], stmp);
00055 
00056 
00057     if (i > topk) 
00058       hi = i-1;
00059     else if (i < topk)
00060       lo = i+1;
00061     else
00062       break;
00063   }
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077   return topk;
00078 }
00079 
00080 
00081 
00083 
00084 int gk_ifkvkselect(size_t n, int topk, gk_fkv_t *cand)
00085 {
00086   int i, j, lo, hi, mid;
00087   gk_fkv_t stmp;
00088   float pivot;
00089 
00090   if (n <= topk)
00091     return n; 
00092 
00093   for (lo=0, hi=n-1; lo < hi;) {
00094     mid = lo + ((hi-lo) >> 1);
00095 
00096     
00097     if (cand[lo].key > cand[mid].key)
00098       mid = lo;
00099     if (cand[hi].key < cand[mid].key)
00100       mid = hi;
00101     else 
00102       goto jump_over;
00103     if (cand[lo].key > cand[mid].key)
00104       mid = lo;
00105 
00106 jump_over:
00107     QSSWAP(cand[mid], cand[hi], stmp);
00108     pivot = cand[hi].key;
00109 
00110     
00111     for (i=lo-1, j=lo; j<hi; j++) {
00112       if (cand[j].key <= pivot) {
00113         i++;
00114         QSSWAP(cand[i], cand[j], stmp);
00115       }
00116     }
00117     i++;
00118     QSSWAP(cand[i], cand[hi], stmp);
00119 
00120 
00121     if (i > topk) 
00122       hi = i-1;
00123     else if (i < topk)
00124       lo = i+1;
00125     else
00126       break;
00127   }
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141   return topk;
00142 }