您的位置:首页 > 其它

算法设计--众数和重数问题(分治法)

2016-10-19 21:36 781 查看
问题描述:

给定含有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; 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 - 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
请按任意键继续. . .
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法