众数问题

本文介绍了一种高效查找多重集合中众数及其重数的方法。通过递归方式将数据集分为左右两部分,并统计目标元素的出现次数来确定众数。此外还提到了排序和使用数组或散列表的替代方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。  
例如,S={1,2,2,2,3,5}。  多重集S的众数是2,其重数为3。  
对于给定的由n 个自然数组成的多重集S,编程计算S 的众数及其重数。
Input  
  输入的第1行多重集S中元素个数n;接下来的n 行中,每行有一个自然数,值在整数范围内 
Output  

  程序运行结束时,将计算结果输出。输出文件有2 行,第1 行给出众数,第2 行是重数。如果很多数的出现次数相同则输出最小的那个。

方法一:递归实现

– 先根据某数X,将小于X的放于其左,大于X的放于其右
– 统计X出现的次数T
– 如果X左边数的个数>T,向左递归
– 如果X右边数的个数>T,向右递归

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 100

int Random(int p, int r){//随机化
        //return rand()*(r-p)/32767+p;
	return rand()%(r-p)+p;
}

void Swap(int* a, int* b){
        int temp; 
		temp= *a;
        *a = *b;
        *b = temp;
}

int Partition(int* y, int p, int r){
        int i = p, j = r+1;
        int x = y[p];
        while(true){
                while(y[++i]<x&&i<r);
                while(y[--j]>x);
                if(i>=j) break;
                Swap(&y[i],&y[j]);
        }
        y[p] = y[j];
        y[j] = x;
        return j;
}

int RandomizedPartition(int* y, int p, int r){
        int i = Random(p,r);
        Swap(&y[i],&y[p]);
        return Partition(y,p,r);
}
void FindModeIndex(int* y,int i,int* left_index,int* right_index)
{
        int mode=y[i];
		int left=i;
		int right=i;
		while(y[--left]==mode);
		while(y[++right]==mode);
		left++;
		right--;
		*left_index=left;
		*right_index=right;
}

void FindMode(int* y, int p, int r, int* mode, int* count){
        int i = RandomizedPartition(y,p,r);
		int left_index;
		int right_index;
		int count_mid,count_left,count_right;
        FindModeIndex(y,i,&left_index,&right_index);
		count_mid=right_index-left_index+1;
		count_left=left_index-p;
		count_right=r-right_index;
		if(count_mid>=*count)
		{
			*mode=y[i];
			*count=count_mid;
		}
        if(count_left>=count_mid) FindMode(y,p,left_index-1,mode,count);
        if(count_right>=count_mid)  FindMode(y,right_index+1,r,mode,count);
		return;
}
int main()
{
	int n;
	int* a;
	int i;
	int mode;
	int count;

	a=(int *)malloc(sizeof(int)*MAX);
	scanf("%d",&n);
	for(i=0;i<n;i++)
	  scanf("%d",&a[i]);
	i=0;
	mode=MAX;
	count=0;
    FindMode(a,0,n-1,&mode,&count);
	printf("mode is %d\ncount is %d\n",mode,count);
	free(a);
	return 0;

}

方法二:先排序,然后再统计,时间复杂度较高。

方法三:利用数组或散列表统计,如果数据分布稠密采用数组,如果数据分布稀疏采用散列表。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值