/*
算法之判断序列中的主元素
题目:已知一个整数序列A=(a0,a1,a2.......an),其中 0 <= ai < n 。若存在ap1 = ap2 = ap3 =......apm =X,且m > n/2,( 0 <= pk < n ,1 <= k <=m ) ,
则称X为序列X的主元素。例如 A = ( 0,5,5,3,5,7,5,5),则5是序列A的主元素;又如 A = ( 0,5,5,3,5,1,5,7),则A没有主元素。假设A中的n个元素保
存在一个一维数组中,请设计一个高效的算法,找出A的主元素
分析:
算法的策略是从前向后扫描数组元素,标记出一个可能成为主元素的元素Num,然后重新计数,确认Num是否为主元素。
算法可以分为以下两步:
1、选取候选的主元素。依次扫描所给数组中的每个元素,将第一个遇到的整数NUm保存到临时变量c中,记录Num出现的次数为1,;若遇到的下一个整数仍为Num,则计数加1,否则计数减1.当计数减到0时,将遇到的下一个整数保存到c中,计数重新标记为1,开始新的一轮计数,即从当前位置开始重复上述过程,直到扫描完全部数组。
2、判断c中元素是否为真正的主元素。再次扫描该数组,统计c中元素出现的次数,若大于n/2,则为主元素;否则序列中不存在主元素
算法实现如下:(算法出自天勤考研之数据结构P53)
*/
int majority(int A[], int n)
{
int i = 0, c = 0, count = 1; //c用来保存候选元素,count用来计数
c = A[0]; //设置A[0]为候选元素
for (i = 1; i < n; ++i) //查找候选元素
{
if (A[i] == c)
{
++count; //对A中的候选元素进行计数
}
else {
if (count > 0)
{
--count; //处理不是候选元素的情况
}
else{
c = A[i];
count = 1; //更换候选元素并重新计数
}
}
}
if (count > 0)
{
for (i = count = 0; i < n; i++) //统计候选元素实际出现的次数
{
if (A[i] == c)
{
++count;
}
}
if (count > n / 2) //确认候选元素
return c;
else
return -1; //不存在主元素
}
}