// 用分治法求众数
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
map<int, int> m;
// 左右两边与中间数相同的数的起始、终止界限
void split(int s[], int n, int &l, int &r)
{
int mid = n/2;
// 连续两个for求与s[mid]相同的数有多少个
for(l=0; l<n; ++l)
{
if (s[l] == s[mid])
break;
}
for(r=l+1; r<n; ++r)
{
if (s[r] != s[mid])
break;
}
}
// num 众数。 maxCnt 重数
void getMaxCnt(int &mid, int &maxCnt, int s[], int n)
{
int l, r;
split(s, n, l, r); // 进行分割。这个函数是本程序的关键
int num = n/2;
int cnt = r-l;
// 更新出现次数最多的数
if (cnt > maxCnt)
{
maxCnt = cnt;
mid = s[num];
m.clear();
m[mid] = maxCnt;
}
else if(cnt == maxCnt)
{
mid = s[num];
m[mid] = maxCnt;
}
// l表示mid左边的个数。左边的个数必须大于 maxCnt才有必要搜寻
if (l >= maxCnt)
{
getMaxCnt(mid, maxCnt, s, l);
}
// n-r表示mid右边的个数, 右边数组的起始地址要变更
if (n-r >= maxCnt)
{
getMaxCnt(mid, maxCnt, s+r, n-r);
}
}
int main(void)
{
int s[] = {1, 2, 2, 2, 3, 3, 5, 6, 6, 6, 6};
//int s[] = {20, 20, 30, 30};
int n = sizeof(s)/sizeof(s[0]);
sort(s, s + n);
int maxCnt = 0;
int num = 0;
getMaxCnt(num, maxCnt, s, n);
map<int, int>::iterator it;
int sum = 0;
for(it = m.begin(); it != m.end(); it++)
{
sum += it->second;
}
if(sum == n) // 唯一没有众数的情景
{
cout << "没有众数" << endl;
}
else
{
for(it = m.begin(); it != m.end(); it++)
{
cout << "众数:" << it->first << ",出现次数:" << it->second << endl;
}
}
return 0;
}