【梦马】程序员必备的九种算法(C语言实现)

(一) BFPRT算法

世界十大经典算法之一,由Blum 、 Floyd 、 Pratt 、 Rivest 、 Tarjan提出,故称为BFPRT算法。

该算法解决的事是如何在n个数中找出第二大的数,抽象下就是求n个数中第k大(小)的数。当时想到的算法是取前k个排序,保存在数组中,然后遍历后n-k,并将每次遍历的数与数组中的k个值比较并重新排序。时间复杂度o(kn),如果k小还好说,但是k大了就不好办了。而BFPRT则在线性时间解决了这个问题。

①将整个数组array[] 5个5个分组,共有n/5组

②在组内使用插入排序

③找到每个组的中位数,组成新的数组(长度为n/5) newArray[]

④递归调用bfprt(newArray, newArray.length/2) 求出其中位数 num

⑤然后利用num进行3方法中进行partition

<num =num >num
⑥若在=num区域时,则返回,否则,选择其中的一半进行后续的partition

代码:

#include <stdio.h>
#include <stdlib.h>
//另类快速排序算法
int compInc(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}

int main()
{
float k; 注意输出格式
int a[1001];
int len ;

while(scanf("%d “,&len)!=EOF){ //要注意输入的终止条件
for(i=0;i<len;i++) //输入
scanf(”%d",&a[i]);
// printf(“递增排序结果:\n”);
qsort(a, len, sizeof(a[0]), compInc);
if(len%2==0) { //奇偶取中位数的方法不一样
k=(a[(len/2)-1]+a[(len/2)]);
printf("%.2f\n",k/2.00);
}
else {
k=a[len/2];
printf("%.2f\n",k);
}
// break;

}
return 0;
}

(二)朴素贝叶斯分类算法

1.1 概述

贝叶斯分类算法时一大类分类算法的总称。贝叶斯分类算法以样本可能属于某类的概率来作为分类依据。朴素贝叶斯分类算法时贝叶斯分类算法中最简单的一种。
注:朴素的意思时条件概率独立性(建议大家对概率中的独立重复事件有所了解)

1.2 算法思想

朴素贝叶斯的思想是这样的:如果一个事物在一些属性条件发生的情况下,事物属于A的概率>属于B的概率,则判定事物属于A。
通俗来说比如,在某条大街上,有100人,其中有50个美国人,50个非洲人,看到一个讲英语的黑人,那么我们是怎么去判断他来自哪里?
提取特征:
肤色:黑,语言:英语

先验知识:
P(黑色|非洲人) = 0.8
P(讲英语|非洲人)=0.1
P(黑色|美国人)= 0.2
P(讲英语|美国人)=0.9
要判断的概率是:
P(非洲人|(讲英语,黑色) )
P(美国人|(讲英语,黑色) )

思考过程:

P(非洲人|(讲英语,黑色) ) 的 分子= 0.1 * 0.8 *0.5 =0.04
P(美国人|(讲英语,黑色) ) 的 分子= 0.9 *0.2 * 0.5 = 0.09
从而比较这两个概率的大小就等价于比较这两个分子的值,可以得出结论,此人应该是:美国人。
其蕴含的数学原理如下:
p(A|xy)=p(Axy)/p(xy)=p(Axy)/p(x)p(y)=p(A)/p(x)p(A)/p(y) p(xy)/p(xy)=p(A|x)p(A|y)
(案例借鉴于 CSDN博主「xujing123qwe」)
由于朴素贝叶斯分类算法代码用C语言实现十分复杂,故不在此处展示

(三) 堆排序

堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了
 我们知道,堆分为"最大堆"和"最小堆"。最大堆通常被用来进行"升序"排序,而最小堆通常被用来进行"降序"排序。
鉴于最大堆和最小堆是对称关系,理解其中一种即可。本文将对最大堆实现的升序排序进行详细说明。

最大堆进行升序排序的基本思想:
① 初始化堆:将数列a[1…n]构造成最大堆。
② 交换数据:将a[1]和a[n]交换,使a[n]是a[1…n]中的最大值;然后将a[1…n-1]重新调整为最大堆。 接着,将a[1]和a[n-1]交换,使a[n-1]是a[1…n-1]中的最大值;然后将a[1…n-2]重新调整为最大值。 依次类推,直到整个数列都是有序的。

实现中用到了"数组实现的二叉堆的性质"。
在第一个元素的索引为 0 的情形中:
性质一:索引为i的左孩子的索引是 (2i+1);
性质二:索引为i的左孩子的索引是 (2
i+2);
性质三:索引为i的父结点的索引是 floor((i-1)/2);

代码如下

#include <stdio.h>
#include <malloc.h>
void HeapAdjust(int a[],int s,int m)//一次筛选的过程

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值