众数问题

来源:互联网 发布:评书下载软件 编辑:程序博客网 时间:2024/04/25 21:51

令E是整数x1,x2..xn。E中x的众数是x在E中出现的次数。如果某个数z的众数大于n/2,则它就是众数

问题1:已知一数列,判断是否存在众数,若存在,则求出众数

问题2:对已知的某个有n个元素的列表,找出所有出现超过n/4次的元素。算法设计应该做o(n)次比较

对于问题1,如果规模比较小的话,用桶式排序,时间复杂度为o(n),对于大规模不太实用了。先排序时间复杂度o(n*lgn),排序后,去取第n/2个数,如果有众数的话,比为第n/2的那个数。但时间复杂度有点高,高于o(n)

引理:如果xi!=xj,删除xi,xj ,原来集合的众数时现在集合的众数。否命题不成立,则需要对求出的众数M,进行检验.

思路;假设众数为M,次数为C.如果xi!=M C=C-1;相等的话,则C=C+1; 还有一种情况,C=0的时候要重新选候选M=a[i] C=1;

问题代码如下:

int majority(int a[],int n)//失败为-1 成功返回众数{int i;int C=1;int M=a[0];for(i=1;i<n;i++){if(C==0){C=1;M=a[i];}else{if(M==a[i]){C=C+1;}else{C--;}}}int sum=0;for(i=0;i<n;i++){if(M==a[i]) sum++;}if(sum>n/2) return M;else return -1;}

对于问题二,修改问题一的众数算法,此时候选为M[3]

代码如下:

int majority_4(int a[],int n){int C[3]={0};int M[3];int i,j;for(i=0;i<3;i++)M[i]=a[0];C[0]=1;for(i=1;i<n;i++){int flag=0;//有C[j]<=0标志为1int find_flag=0;//找到a[i]==M[j]for(j=0;j<3;j++){if(C[j]<=0){C[j]=1;M[j]=a[i];flag=1;break;}else{if(M[i]==a[i]) break;}}if(flag==1) continue;for(j=0;j<3;j++){if(a[i]==M[j]){C[j]++;find_flag=1;}}if(find_flag==1) continue;for(j=0;j<3;j++){C[j]--;}}int sum[3]={0};for(i=0;i<n;i++){for(j=0;j<3;j++){if(C[j]>0&&M[j]==a[i]){sum[j]++;break;}}}int flg=0;for(j=0;j<3;j++){if(sum[j]>n/4){cout<<"  "<<M[j]<<endl;flg=1;}}if(flg==1) return 1;else return 0;}




0 0
原创粉丝点击