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

问题描述:
给定含有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
请按任意键继续. . .
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章