问题描述:
给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。例如,S={1,2,2,2,3,5}。多重集S的众数是2,其重数为3。对于给定的n个自然数组成的多重集S,计算S的众数及其重数 。
问题分析:
1、 分治法
分治法解题过程主要分为分、治、合三个步骤“,应用该方法的基本过程如下:
(1) 将原问题分解为若干个规模较小的子问题
(2) 对这些子问题分别求解
(3) 对各个子问题的解进行合并
2、 众数:一组数据中出现次数最多的数值,叫众数。有时一组数据中有多个众数。
重数:重数是指该众数出现的次数。
3、 根据以下实例理解分治法求解众数及其重数
给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。
例如,S = {1,2,2,2,3,5}。
多重集S的众数是2,其重数是3.
算法实现:
// Test_01.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
void split(int s[],int n,int &l,int &r){
int mid = n/2;
for(l = 0; lif(s[l] == s[mid])
break;
}
for(r = l+1;rif(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 - 1;
if(cnt > maxCnt){
maxCnt = cnt;
mid = s[num];
}
//l表示左边的个数,左边的个数必须大于中位数的个数,才有进行搜索的意义
if(l+1 > maxCnt){
getMaxCnt(mid, maxCnt, s, l+1);
}
//同理,右边的个数将要大于中位数的个数才有继续搜寻的意义,同时右边数组的起始位置进行改变
if(n-r > maxCnt){
getMaxCnt(mid, maxCnt, s+r, n-r);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int s[] = {1,2,2,2,3,5};
int n = sizeof(s)/sizeof(s[0]);
int maxCnt = 0;
int num = 0;
getMaxCnt(num ,maxCnt, s, n);
printf("%d %d\n",num,maxCnt);
return 0;
}
运行结果
由于初始数组为int s[] = {1,2,2,2,3,5};所以运行结果中众数为 2 重数为 3
2 3
请按任意键继续. . .