c语言递归算法找众数,众数问题-递归和分治

问题描述

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

例如:

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.

*/

分治算法是一种基于分治策略的算法,它将问题分解为若干个子问题,然后递归地解决这些子问题,最后将这些子问题的解合并起来得到原问题的解。在求解众数问题时,可以使用分治算法来解决。 众数即为出现次数最多的数。要求解一个数组中的众数,可以将数组分为两个部分,分别求出左右两个部分的众数,然后再将两个众数进行比较,选出其中的众数分治算法求解众数的步骤如下: 1. 将数组分为左右两个部分,分别递归求解左右两个部分的众数。 2. 如果左右两个部分的众数相同,则直接返回这个众数。 3. 如果左右两个部分的众数不同,则统计左右两个部分中各自的众数出现的次数,选出次数更多的那个数作为整个数组众数。 Java代码实现如下: ```java public int majorityElement(int[] nums) { if (nums.length == 1) { return nums[0]; } int mid = nums.length / 2; int[] left = Arrays.copyOfRange(nums, 0, mid); int[] right = Arrays.copyOfRange(nums, mid, nums.length); int leftMajority = majorityElement(left); int rightMajority = majorityElement(right); if (leftMajority == rightMajority) { return leftMajority; } int leftCount = count(nums, leftMajority); int rightCount = count(nums, rightMajority); return leftCount > rightCount ? leftMajority : rightMajority; } private int count(int[] nums, int num) { int count = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == num) { count++; } } return count; } ``` 这样,就可以使用分治算法来解决众数问题了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值