隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
          數據加載中……

          得到第K個大的數算法研究

          本文為原創,如需轉載,請注明作者和出處,謝謝!

              第一種算法是最容易想到的,就是利用快速排序的思想,將一個數組分成以某一個數X為軸,左邊的所有的數都比X小,而右邊的數都比X大。但我快速排序不同的是,在這個算法中只考慮X的一邊,而不是兩邊都考慮。

             如果X的位置是i,那么要得到第k個數,如果k<=i, 那么這個數一定在i的左邊,否則在i的右邊。

          源碼如下:

          #include <stdio.h>
          #include 
          <stdlib.h>
          int new_random(int min, int max)
          {
              
          return (min + (int)(((float)rand()/RAND_MAX)*(max - min)));
          }
          void swap(int *a, int *b)
          {
              
          int c = *a;
              
          *= *b;
              
          *= c;
          }

          int partition(int A[], int p, int r)
          {
              
          int i = p - 1, j;
              
          for(j = p; j < r; j++)
              {
                  
          if(A[j] <= A[r])
                  {
                      i
          ++;
                      swap(
          &A[i], &A[j]);
                  }
              }
              swap(
          &A[i + 1], &A[r]);
              
          return i + 1;
          }

          int randomize_partition(int A[], int p, int r)
          {
              
          int i = new_random(p, r);
              swap(
          &A[i], &A[r]);
              
          return partition(A, p, r);
          }

          //第一種算法
          int randomized_select(int data[], int p, int r, int k)
          {
              
          if(k > (r - p + 1)) return 0;
              
          if(p == r) return data[p];
              
          int i = randomize_partition(data, p, r);
              
          //int i = partition(data, p, r); //不好使,死循環, 必須用隨機數,在第二步時總是在最大數處劃分

              
          int count = i - p + 1;
              
          if(k <= count)
                  
          return randomized_select(data, p, i, k);
              
          else
                  
          return randomized_select(data, i + 1, r, k - count);
          }


              另外一種對這種算法做了一下改進,即將數組每5個數一組進行排序,然后取得它的中位數,再對這些中位數進行排序。然后先出的軸X最比較好的,因此X的左邊和右邊的數總是很平均,所以平均查找速度更快。算法如下:

          void quicksort(int data[], int b, int e)
          {
              
          if(b < e)
              {
                  
          int k = partition(data, b, e);
                  quicksort(data, b, k 
          - 1);
                  quicksort(data, k 
          + 1, e);
              }
          }

          int partition1(int A[], int p, int r, int x)
          {
              
          int i = p - 1, j;
              
          for(j = p; j <= r; j++)
              {
                  
          if(A[j] <= x)
                  {
                      i
          ++;
                      swap(
          &A[i], &A[j]);
                  }
              }
              A[i 
          + 1= x;
              
          return i + 1;
          }
          //第二種算法
          int select_new(int data[], int p, int r, int k)
          {
              
          if(r - p < 75)
              {
                  quicksort(data, p, r);
                  
          return data[p + k - 1];
              }   
              
          int i;
              
          for(i = 0; i <= (r - p - 4/ 5; i++)
              {
                  quicksort(data, p 
          + 5 * i, p + 5 * i + 4);
                  swap(
          &data[p + 5 * i + 2], &data[p + i]);
              }
              
          int x = select_new(data, p, p + (r - p - 4/ 5, (r - p - 4)/10); // 得到更好的軸X
              i = partition1(data, p, r, x);
              
          int count = i - p + 1
              
          if(k <= count)
                  
          return select_new(data, p, i, k);
              
          else
                  
          return select_new(data, i + 1, r, k - count);
          }

          int main()
          {
              
          int data[] = {3173481167812-1100};
              printf(
          "%d\n", randomized_select(data, 092));
              
          int data1[] = {3173481167812-1100};
              printf(
          "%d\n", select_new(data1, 092));
             
               
          return 0;
          }





          Android開發完全講義(第2版)(本書版權已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2008-05-12 20:55 銀河使者 閱讀(2046) 評論(0)  編輯  收藏 所屬分類: algorithm 、C/C++ 、 原創

          主站蜘蛛池模板: 金沙县| 卓尼县| 祁阳县| 武城县| 龙州县| 丽水市| 县级市| 太湖县| 肃宁县| 滨州市| 遂溪县| 万宁市| 内乡县| 临洮县| 昌平区| 武功县| 遂宁市| 诏安县| 岢岚县| 石阡县| 大余县| 五家渠市| 刚察县| 双牌县| 秦安县| 鹤庆县| 连云港市| 噶尔县| 通河县| 九龙坡区| 鸡泽县| 衡山县| 陆良县| 方山县| 安庆市| 陈巴尔虎旗| 商洛市| 克拉玛依市| 巴林左旗| 七台河市| 周口市|