c语言分治法求众数重数_分治法之众数问题

本文介绍了如何使用C语言实现分治法来求解众数问题。通过对比传统的数组方法和分治法,阐述了分治法的优势,并提供了包含详细注释的分治法代码实现。在代码中,先对数据进行排序,然后通过中位数划分数组,递归查找众数。
摘要由CSDN通过智能技术生成

实验总结

刚开始我没有想到可以用分治法来做,用的是数组来做。做完以后发现算法太过复杂,而且处理较大的n时,时间复杂度和空间复杂度都比较大。于是我参考了算法答案那本书,学到了分治法来解决这道题。但是在完成了用分治法的代码以后,我发现了问题:

输出应该为:

2

4

分治法解决这道题有一个大前提:多重集中的元素是有序的(递增或者递减),所以很有必要给多重集加入一个排序的算法.

附录:(要求代码里各行要有注释)

自己的代码(性能不够好,太过复杂)

int main()

{

int n;

cin>>n;

int a[n];

for(int i=0;i

{

cin>>a[i];

}

f(n,a);

return 0;

}

void f(int n,int *a)//n为多重集元素的个数,a是存放数组的元素

{

int b[n][2];//b[][0]存放元素的种类,B[][1]存放每种元素的个数

b[0][0]=a[0];

b[0][1]=1;

int h=0;//数组b中已初始化的行的标号

int flag=0;//判断b中是否已经有该元素了

for(int i=1;i

{

for(int j=0;j<=h;j++)

{

if(a[i]==b[j][0])//判断元素a[i]是否已经在数组b中存在

{

b[j][1]++;

flag=1;

}

}//存在的话,把b[j][1]加1,flag变为1,否则不做操作

if(flag==0)

{

h++;

b[h][0]=a[i];

b[h][1]=1;

}

flag=0;

}//不存在的话,flag为0,此时把a[i]加入到数组之中,并把个数变为1

int temp=b[0][1];

int t=0;

for(int i=0;i<=h;i++)//寻找b中数目最多的那个元素

{

if(temp

{

temp=b[i][1];

t=i;

}

}

cout<

}

参照答案和csdn博客所改的代码:

int main()

{

int n;

cin>>n;//元素个数

int a[n];

for(int i=0;i

{

cin>>a[i];

}//数组用于存放元素

int l=0;//数组的首个标号

int r=n-1;//数组的最后一个标号

int largest=0;//重数的初始化

int elem=-1;//众数的初始化

mode(a,l,r,largest,elem);//调用函数

cout<

return 0;

}

//用于求数组的中位数的函数↓

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

{

return a[(l+r)/2];

}

//以med来划分数组↓ !!!关键函数

void split(int *a,int med,int l,int r,int &l1,int &r1)

{

for(l1=l;l1<=r;l1++)

{

if(a[l1]==med)

break;

}//l1表示首个等于med的数组下标

for(r1=l1+1;r1<=r;r1++)

{

if(a[r1]!=med)

break;

}

r1--;

}//r1表示最后一个等于med的数组下标

void mode(int *a,int l,int r,int &largest,int &elem)

{

int l1,r1;//分割后左边子数组的右界和右边子数组的左界

int med=median(a,l,r);//midian函数用于找到数组的中位数

split(a,med,l,r,l1,r1);//以med中位数来分割数组

if(largest

{

largest=r1-l1+1;

elem=med;

}//每次递归更新众数和重数的值

if(l1-l>largest)

mode(a,l,l1-1,largest,elem);//判断左边是否值得递归(只有l1-1大于largest才有必要搜寻)

if(r-r1>largest)

mode(a,r1+1,r,largest,elem);//判断右边是否值得递归

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值