c语言寻找多数元素算法,算法 寻找多数元素

寻找多数元素

一、问题描述:

令A[1.....n]是一个整数序列,A中的整数a如果在A中出现的次数多于[n/2]次,那么a就称为多数元素。例如在序列1,3,2,3,3,4,3中,3是多数元素,应为7个元素中它出现的次数是4。有几种方法可以解决这个问题。

法【1】:蛮力算法

把每一个元素和其他元素比较,并且对每个元素计数,如果,

某个元素的计数大于[n/2],就可以断言它是多数元素;否则,在序列中就没有多数元素。但是,这样的比较次数是n(n-1)/2=Θ(n²),这种方法的代价太昂贵。所以称为蛮力算法。

法【2】:排序算法

另外一种比较有效地算法是,对这些元素排序,并且计算每个

元素在序列中出现多少次。这在最坏的情况下的代价是Θ(n log n)。因为在最坏情况下,排序这一步需要Ω(n log n)次比较。

法【3】:中间元素法

另外一种算法是寻找中间元素,就是第[n/2]元素。因为多数

元素,在排序的序列中一定是中间元素,可以扫描这个序列来测试中间元素是否确实是多数元素。由于中间元素可以在Θ(n)时间内找到,这个方法要花费Θ(n)时间。

二、算法分析:

通过归纳法导出一个漂亮算法,可以很好的解决这个问题。

1、该算法基于以下结论:

在原序列中除去两个不同的元素后,那么在原序列中的多数元素在新序列中还是多数元素。

2、接下来是其算法过程:

将计数器置1,并令c=A[1],从A[2]开始,逐个地扫描元素,如果被扫描的元素和c相等,则计数器加1;如果元素不等于c,则计数器减1;如果所有的元素都已经扫描完毕并且计数器大于0,那么返回c作为多数元素的候选者。如果在c和A[j](1

3、伪代码形式如下:

算法:MAJORITY

输入:n个元素的数组A[1....n]。

输出:若存在多数元素,则输出;否则输出none。

1.c ←candidate(1)

2.count ←0

3.for j ←1 to n

4. if A[j]=c     then  count←count+1

5.end for

6.if count>[n/2]   then  return c

7.else return none

过程  candidate(m)

1.j←m; c←A[m];count←1

2.while j0

3. j←j+1

4. if A[j]=c  then count←count+1

5. else count←count-1

6.end while

7.if j=n then  return c

8.else  return candidate(j+1)

三、源代码(c++):

#include

using namespace std;

int candidate(int);

int *A;

int n;

int main()

{

cout<

cin>>n;

A=new int[n+1];

cout<

for(int i=1;i<=n;i++)

{

cout<

cin>>A[i];

}

int c,count=0;

c=candidate(1);

for(int j=1;j<=n;j++)

{

if(A[j]==c)

count++;

}

if(count>(n/2))  //check again,c is the majority element

cout<

else

cout<

delete[] A;

return 0;

}

int candidate(int m)

{

int j,c,count;

j=m;c=A[m];count=1;

while(j0)

{

j++;

if(A[j]==c)

count++;

else

count--;

}

if(j==n)

return c;

else

return candidate(j+1);

}

四、分析迭代过程:

输入的序列为0,5,1,0,0,0,5,0.  n=8

Candidate(1)

j=1,c=0,count=1

j=2,A[2]=5(!=c),count=0

Candidate(3)

j=3,c=1,count=1

j=4,A[4]=0(!=c),count=0

Candidate(5)

j=5,c=0,count=1

j=6,A[6]=0(=c),count=2

j=7,A[7]=5(!=c),count=1

j=8,A[8]=0(=c),count=2

j=n     return c (c=0)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值