寻找一个主元(出现次数大于总元素的一半)的算法

摘要(1):当一个元素个数为N的数组中,某个元素出现的次数超过N/2次,就叫这个元素为主元;
(2)现实现一种教科书的算法:{1}:找出一个主元的候选元(难点){2}确定该候选元是否是主元(简单)
首先:对数组A[N]进行遍历,比较A1与A2,如果A1与A2相同,则将A1放入数组B中,否则不进行任何处理。然后比较A3与A4,以相同方式直到遍历整个数组,然后递归的对B进行遍历。最后找出的就是候选元。
(3)分析该算法:首先证明该算法的合理性:{1}为方便起见,设N=2k,如果x是主元,则x至少出现k+1次。
{2}对N进行两两分组设x与自己配对m次,(m显然不可能为0,否则N>2k,这意味着主元一定进入B),则x与其他元素配对k+1-2m次(这些元素都不可能进入B,因为它们与x配对且不是x),则剩下元素(不一定是同一个元素,可以是y,z,w……)最多配对次数为:k+1 - (m+ k+1-2m)= m-1
{3}m>m-1,因此x在B依旧是主元,因此递归的对B进行算法是成立的。(初始情况成立,类似数学归纳法的逻辑).
其次讨论N = 2k + 1时的情况,同样的逻辑分析是适用的,需要注意的是在代码上的处理
(4)对N = 2k+1的代码处理,首先依然对N = 2k进行算法,现在讨论三种情况,第一种没有主元,那么不需要进行多余处理.
第二种有主元x,且x在A[N-1](下标从0开始),那么利用(3)的分析可知x在B出现m次,而其余元素可能在`B出现的次数是k-(m+k-2m)= m,注意,x不在是主元了,因此必须要对x进行处理,将最后一个x加入B。
最后一种,x是主元,但都分布在前N-1个,那么与N=2k时一样,不需要处理。

#include "stdafx.h"
#include "stdlib.h"
#define Max_N 15
#define Error -1999

int find(int *A, int N)
{
    int b[Max_N];
    int j = 0,i = 0;
    int num;
    if (N==0)
    exit(-1);
    if (N == 1)
    {
        if (A[N-1]!= Error)
        return (A[N-1]) ;
        else 
            return Error;
    }
    for (i = 0;i<=N-2;i += 2)
    {

        if (A[i] == A[i+1])
            b[j++] = A[i];
    }

    if (N%2)//处理N为奇数
    {
        for ( i=0,num=0;i<=j-1;i++) 
       if (b[i]==A[N-1]) num++;//考察最后一个元素是不是主元
      if (num+1>(j+1)/2) b[j++]=A[N-1];
    }

    return(find(b,j));
}
int _tmain(int argc, _TCHAR* argv[])
{

    int A[Max_N] = {5,5,3,5,6,7,5,3,5,3,1,5,5,2,5};
    int s = find(A,Max_N);
    int num = 0;
    if (s!= Error){
    for(int i =0;i<=Max_N-1;i++)
    {
        if(s == A[i])
            num++;
    }
    if (num>Max_N/2)
        printf("the majority is %d",s);
    else
        printf("nothing");
    }
    else
        printf("nothing");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值