zoukankan      html  css  js  c++  java
  • Select算法(最坏复杂度O(n))

      1 #include<iostream>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <algorithm>
      5 #include <string>
      6 #include <string.h>
      7 using namespace std;
      8 
      9 const int nMax = 3000;
     10 int A[nMax+1];
     11 int B[nMax+1];//用来每次5分法后保存要比较的值在A中的下标
     12 int AIndex[nMax+1]; //用来保存A的初始化下标
     13 
     14 //通过插入排序获取中位数下标
     15 int InsertSort(int A[], int B[], int start, int end)
     16 {
     17     if (start == end)
     18     {
     19         return B[start];
     20     }
     21 
     22     for (int i = start+1; i <= end; ++i)
     23     {
     24         int num = A[B[i]];
     25         int j = i-1;
     26         for ( ; j >= start; --j)
     27         {
     28             if (num < A[B[j]])
     29             {
     30                 A[B[j + 1]] = A[B[j]];
     31             }
     32             else
     33             {
     34                 break;
     35             }
     36         }
     37         A[B[j + 1]] = num;
     38     }
     39 
     40     return B[(start + end)/2];
     41 }
     42 
     43 //获取中位数的中位数的下标
     44 int GetMidMid(int A[], int AIndex[], int k, int n)
     45 {
     46     if (k == n)
     47     {
     48         return AIndex[n];
     49     }
     50 
     51     int len_s = n - k + 1;
     52     //筛选出n/5份的中位数
     53     int mod = len_s % 5;
     54     int len = len_s / 5 + (mod != 0);
     55     for (int i = 1, j = k; i<= len && j <= n-mod; ++i, j+=5)
     56     {
     57         B[i] = InsertSort(A, AIndex,j, j+4);
     58     }
     59     if (mod != 0)
     60     {
     61         B[len] = InsertSort(A, AIndex, n - mod + 1, n);
     62     }
     63     return GetMidMid(A, B, 1, len);
     64 }
     65 
     66 //原址排序
     67 int Partition(int A[], int p, int n)
     68 {
     69     int pivot = A[n];
     70     int j = p - 1;
     71     for (int i = p; i <= n - 1; ++i)
     72     {
     73         if (A[i] <= pivot)
     74         {
     75             j++;
     76             swap(A[j], A[i]);
     77         }
     78     }
     79 
     80     swap(A[j + 1], A[n]);
     81     return j + 1;
     82 }
     83 
     84 int Select(int A[], int k, int n, int i)
     85 {
     86     if (k == n)
     87     {
     88         return A[n];
     89     }
     90 
     91     int midValueIndex = GetMidMid(A, AIndex, k, n);
     92 
     93     //将该中位数作为主元(pivot element)
     94     //使用一次原址重排
     95     int pivot = A[midValueIndex];
     96     swap(A[midValueIndex], A[n]);
     97     int mid = Partition(A, k, n);
     98 
     99     int t = mid - k + 1;
    100     if (i == t)
    101     {
    102         return A[mid];
    103     }
    104     else if (i < t)
    105     {
    106         return Select(A, k, mid-1, i);
    107     }
    108     else
    109     {
    110         return Select(A, mid+1, n, i-t);
    111     }
    112 }
    113 int main(int argc, char** argv)
    114 {
    115     int n = 1111;
    116     for (int i = 1; i <= n; ++i)
    117     {
    118         A[i] = i;
    119         AIndex[i] = i;
    120     }
    121 
    122     //for (int i = 1; i <= n; ++i)
    123     //{
    124     //    cout << A[i] << " ";
    125     //}
    126     //cout << endl;
    127     
    128     int equalNum = 0;
    129     for (int i = 1; i <= n; ++i)
    130     {
    131         //随机排列A数组
    132         for (int i = 1; i <= n; ++i)
    133         {
    134             int j = i + rand() % nMax;
    135             //swap(A[i], A[j]);
    136             A[i] = j;
    137         }
    138 
    139         int ans1 = Select(A, 1, n, i);
    140         sort(A + 1, A + n + 1);
    141         int ans2 = A[i];
    142 
    143         if (ans1 == ans2)
    144         {
    145             equalNum++;
    146         }
    147     }
    148     cout << n << " " << equalNum << endl;
    149     return 0;
    150 }
  • 相关阅读:
    简化得最没道理的6个汉字,让人大跌眼镜
    简化得最没道理的6个汉字,让人大跌眼镜
    简化得最没道理的6个汉字,让人大跌眼镜
    java面向对象高级分层实例_测试类(main方法所在的类)
    java面向对象高级分层实例_测试类(main方法所在的类)
    java面向对象高级分层实例_测试类(main方法所在的类)
    java面向对象高级分层实例_数据库操作类
    squared-error loss is much more repaidly updated than mean-absolute-deviation when searching for splits
    Greedy Function Approximation:A Gradient Boosting Machine
    ridge regression 无惩罚,导致预测结果空间过大而无实用价值
  • 原文地址:https://www.cnblogs.com/heqinghui/p/9164292.html
Copyright © 2011-2022 走看看