冒泡排序是一种复杂度为O(n2)的低效排序算法。它通过不断比较元素并交换位置使一个元素到达有序集合的正确位置上。
冒泡排序的过程是把相邻的数据元素进行交换,从而逐步将待排序序列变成有序序列。冒泡排序的基本思想是:从头扫描待排序序列,在扫描的过程中顺次比较相邻两个元素的大小。
下面以升序为例介绍排序过程。
(1)在第一轮排序中,对n个记录进行如下操作。
①对相邻的两个记录的关键字进行比较,逆序时就交换位置。
②在扫描的过程中,不断向后移动相邻两个记录中关键字较大的记录。
③将待排序记录序列中的最大关键字记录交换到待排序记录序列的末尾,这也是最大关键字记录应在的位置。
(2)进行第二轮冒泡排序,对前n-1个记录进行同样的操作,其结果是使次大的记录被放在第n-2个记录的位置上。
(3)继续进行排序工作,在后面几轮的升序处理也反复遵循了上述过程,直到排好顺序为止。如果在某一轮冒泡过程中没有发现一个逆序,就可以马上结束冒泡排序。整个冒泡过程最多可以进行n-1轮,如图演示了一个完整的冒泡排序过程。
使用C语言实现冒泡排序的算法代码如下所示:
/*对数组 r 做冒泡排序,length为数组的长度*/
typedef int KeyType;
typedef struct {
KeyType key;
} RecordType ;
void BubbleSort(RecordType r[], int length ){
n=length;
change=TRUE;
for ( i=1 ; i<= n-1 && change ;++i ) {
change=FALSE;
for ( j=1 ; j<= n-i ; ++j)
if (r[j].key> r[j+1].key ) {
x= r[j];
r[j]= r[j+1];
r[j+1]= x;
change=TRUE;
}
}
} /* BubbleSort */
C语言冒泡排序源程序?
相信学过C语言的朋友都知道,在C语言中,常用的排序算法有:冒泡排序、快速排序、插入排序、选择排序、希尔排序、堆排序以及归并排序等等。就算没有用过,相信大家也有所耳闻。在这里呢,小编主要是想和大家一起来探讨探讨C语言的冒泡排序法,大家有什么好的建议可以在评论里给我留言,希望我们相互学习,共同进步。
1、所谓冒泡排序法,就是对一组数字进行从大到小或者从小到大排序的一种算法。具体方法是,相邻数值两两交换。从第一个数值开始,如果相邻两个数的排列顺序与我们的期望不同,则将两个数的位置进行交换(对调);如果其与我们的期望一致,则不用交换。重复这样的过程,一直到最后没有数值需要交换,则排序完成。一般地,如果有N个数需要排序,则需要进行(N-1)趟起泡,我们以从小到大排序为例来看一下,具体情况如下图所示:
2、首先,为了实现效果,我们得先定义一组待排序的数列以及各个变量。具体情况如下图:
3、算法的实现,具体情况如图:
4、运行结果显示。具体情况如图:
5、按照上面的程序,在第五趟(i=5)起泡时,计算机不仅要对“1,5,6,4”两两进行比较并排序,还要对“7,8,9,13”进行两两比较并排序,而“7,8,9,13”在第四趟起泡时就已经排序好了,所以再进行比较的话,就显得非常多余。图示如下:
6、在上面程序的基础上进行优化。具体情况如图所示:
7、优化后的输出结果。如图所示:
"
设计C语言算法时,怎样才算合格?感觉算法好难,基于数组的归并排序算法该如何理解?
。
我的上个回答简要讨论了下什么是算法,并且介绍了C语言程序开发中比较基本的数组排序算法——插入排序法,如果题主看了,应该有助于理解本题。
事实上,让C语言编程具有魅力的是算法,拿到问题,能够设计出解决方案并且完成代码的是程序员,只会按照步骤编码的是码农。
这是上个回答的主题,有朋友看到也有感而发:在评论区说,“程序是骨架,算法才是灵魂”。的确,C语言程序只是指令,计算机只会冷冰冰的按照指令办事,它并不能解决问题,真正解决问题的还是人。
什么样的算法才是好的算法呢?
假设计算机是无限快的,并且存储器是免费的无限大的,那最好的算法就是最容易实现的算法。
然而,计算机也许是快的,但它们不是无限快。存储器也许是廉价的,但不是免费的。所以计算时间是一种有限资源,存储器的空间也一样。优秀的程序员应该尽力设计出开销更小的算法。
下面再讨论下C语言程序开发中,数组的归并排序算法,这种算法也是比较经典的排序法,在数组元素非常多的情况下,效率远远高于插入排序法。
什么是归并排序呢?
归并排序的定义,希望了解“一本正经”的官方书面定义可以自行百科。这里就不写了,因为“冷冰冰的”书面定义对不了解它的人来说太难懂。
我打算用一些容易理解的例子来解释它。
假设有一个C语言数组需要排序,那数组长度为多长最简单呢?显然是长度为 1 时,排序最简单,什么都不需要做,就能够排好序。
归并排序的基本思路就是这样:把长数组一直拆分下去,直到最后不能拆分为止,这时长数组被拆分为若干个长度为 1 的数组,长度为 1 的数组显然是排好序的了。
例如下图是一个长度为 5 的数组,为了排序,先把它拆分到不能继续拆为止。
接着,只要把这些排好序的子数组按照从小到大的顺序合并,就可以得到最终排好序的数组了。
好了,现在知道归并排序的算法了,那怎样使用 C语言编程完成这个算法呢?
使用C语言编程实现归并排序算法
归并排序算法总体可以分为两步:拆分数组,合并数组。先来看看怎样使用C语言实现数组的拆分。
使用C语言拆分数组
对数组拆分有多种方法,这里选择平分法。
如果使用 start 表示数组头,end 表示数组尾,每次平均拆分,都会将数组分为 start 到 mid,和 mid+1 到 end 两部分,其中 mid 表示中间点,所以 mid = (start+end)/2。就这样一直拆分下去,直到不能继续拆分为止。
不能拆分时,start 应该不再小于 end。
拆分数组的数学描述完毕了,容易看出,递归(如果题主对C语言的递归不理解,可以查看我之前的问答或者文章。)非常适合解决这样的问题。我们现在用C语言来实现这样的拆分,先确定递归的基础条件:
拆分过程会在 start 不再小于 end 时停下。其他情况时,拆分会继续下去,相关C语言代码如下,请看:
divide(start, mid); 负责拆分前半段,divide(mid+1, end); 负责拆分后半段。这样的 divide 函数可以把数组拆分到不可拆分为止。
使用C语言合并数组
使用 divide 函数把数组拆分完毕后,就可以按照从小到大的顺序把各个元素合并到原来的数组了。
由于两个子序列都已经排好序了,所以 merge() 函数的C语言代码很简单,每次循环取两个子序列中最小的元素进行比较,将较小的元素取出放到最终的排序序列中,如果其中一个子序列的元素已取完,就把另一个子序列剩下的元素都放到最终的排序序列中。
使用C语言实现数组的归并排序
数组的拆分和合并函数都写好了,可以把它俩结合起来,实现数组的排序了。
测试C语言实现的归并排序
这里使用 8 个元素的数组做测试:
编译并执行这段C语言代码,发现数组被成功排序了。
到这里,相信题主应该明白如何使用C语言实现数组的归并排序了。它和插入排序算法都属于排序算法,但是二者的效率差异性却很大。
程序员一般如何衡量算法的效率呢?数组的插入排序法和归并排序法的效率差异性到底有多大呢?我之前的文章已经比较详细的讨论过,题主可以点击我的主页查看。
欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。