众数分治法java,众数问题-递归和分治

问题描述

给定一个数组,找出其中出现次数最多的那个元素(即众数)。

例如:

1 2 2 2 3 5

众数是: 2

算法思路:先排序  后用分治法计算求解

分治法求解代码如下:

#include

#include

#include

using namespace std;

/*----------快速排序*/

int Partition(int *a , int l , int r)

{

int i = l , j = r+1;

int x = a[l];

while(true){

while(a[++i] < x && i < r);

while(a[--j] > x);

if(i >= j) break;

swap(a[i] , a[j]);

}

a[l] = a[j];

a[j] = x;

return j;

}

/*------------随机选择中位数排序*/

int RandomizedPartitiom(int *a , int l , int r)

{

srand(time(NULL));

int i = rand()%(r-l)+l;

swap(a[i] , a[l]);

return Partition(a , l , r);

}

/*----------------按中位数划分成两段*/

void split(int *a , int m , int l , int r , int *left , int *right)

{

int med = a[m];

*left = *right = m;

/*--------------------将 == 中位数的元素剔除:及 right-left+1 == 众数的个数*/

while(a[--(*left)] == med);

while(a[++(*right)] == med);

(*left)++;

(*right)--;

}

/*---------------分治法求解*/

void mode(int *a , int l , int r , int *largest , int *count)

{

int m = RandomizedPartitiom(a , l , r);//----查找中位数

int left , right;

split(a , m , l , r , &left , &right);//---按中位数分成2段

if(*largest < right-left+1){//-----保留众数个数最大值,及众数下标

*largest = right-left+1;

*count = m;

}

if(left-l > *largest) mode(a , l , left-1 , largest , count);//左边个数大于众数个数

if(r-right > *largest) mode(a , right+1 , r , largest , count);//右边个数大于众数个数

}

/*----------main()*/

int main()

{

int n;

cout<

cin>>n;

int a[n];

int largest = 0 , count = 0;

cout<

for(int i = 0 ; i < n ; i++)

cin>>a[i];

mode(&a[0] , 0 , n-1 , &largest , &count);

cout<

return 0;

}

/*

请输入集合S的元素个数n:

6

请输入元素:

1 2 2 2 3 5

众数是:2 重数是:3

Process returned 0 (0x0) execution time : 7.504 s

Press any key to continue.

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值