冒泡排序

Quicksort
快速排序是对冒泡排序的一种改进。那么就不得不先说一下冒泡排序!

提出问题:给定的一个随机数组,将数组排好序输出。

一、解决思路:将数组第一个位置上的元素与其他所有元素一一对比,得到最小值并将其放到第一个位置;将数组第二位置上的元素与第三个到最后一个元素一一对比,得到最小值并将其放到第二个位置上;依次循环第三个、四个位置上一直到数组最后一个位置。便可得到排好的顺序。(思考:这是冒泡排序吗?先实现一下)
第一次写的代码如下:

通过查询资料、技术贴等等,又对其进行了代码优化,把自己的代码和别人的代码相对比,发现差距很大。由衷感慨:懂和写出来是两码事,而写出来和写好又是另外两码事!下面是大神的代码,我对自己的编码能力惭愧不已:
void betterFirst(){
    int a[10] = {2,4,6,1,9,8,3,7,10,5};
    for(int i=0;i<10;i++)
        for(int j=i+1;j<10;j++)
            if(a[i]>a[j])//这里是i和j
                swap(&a[i],&a[j]);
   }
ok,至此,确实已经实现了正确的排序。但是,还是那个问题:这是冒泡排序吗?从大学刚学C语言就开始学,我一直没弄清它与冒泡排序到底有什么区别。
二、下面我们来认识一下真正的冒泡。
冒泡思想:把这些数看成大小不一的泡,然后将最小的泡冒到最上面,其他大小依次排列;或者将最大的泡沉到最下面,剩下依次排列,一个道理。
将最小的泡冒到最上面思想:将最后位置的元素与倒第二位置的元素比较,若小于就交换,否则将倒第二元素和倒第三元素比较,规则依旧;倒第三元素和倒第四个元素相比较;依次运行下去,直到第二个元素和第一个元素比较为止。第一次循环结束,结果:得到一个最小值,并把它放在了第一个位置。
再进行第二次循环,同上,将最后位置的元素和倒第二位置元素比较,再将倒第二位置元素与倒第三位置元素比较,依次进行下去,由于第一次循环已经将最小值放在了第一个位置,所以这次循环只需要进行到第三个位置元素与第二个元素比较,第二次循环结束,结果:得到了次小的值,并将其放在了第二个位置。
依次进行循环,最后一轮比较最后一个元素和倒第二个元素。至此,排序完成。代码如下:
void bubblesort(){
    int a[10] = {2,4,6,1,9,8,3,7,10,5};
    for(int i=0;i<10;i++)
        for(int j=9;j>i;j--)
            if(a[j]<a[j-1])//这里是j和j-1
                 swap(&a[j],&a[j-1]);
}
将最大的泡沉到最下面:只是从第一个元素开始,依次两两(此处两两是指位置一和二、二和三、三和四等,很多人在此处容易混淆)比较,将最大元素放到最后位置,依次循环,不再重复。代码如下:
void bubblesort2(){
    int a[10] = {2,4,6,1,9,8,3,7,10,5};
    for(int i=9;i>=0;i--)
        for(int j=0;j<i;j++)
            if(a[j]>a[j+1])
                swap(&a[j],&a[j+1]);
}
这个版本的for循环反过来写的方式比较常见。
三、区别到底在哪呢?
第一:方法一依次循环,是固定一个位置不动,将该位置的元素依次与后面的其他元素相比较,一次遍历后,这个位置上就是最小/大值;冒泡是从后到前两两(上面已经解释)比较,是流动性的比较。其实说到底,我写的这个是选择排序!!!
第二:方法一每次循环虽然都选择了未排序中的最小的元素,并放在了适当位置,但是仍将本来比较小的元素放到了后面去了,而冒泡只把小元素提前,不会发生上述情况。

其实无论是冒泡排序还是选择排序都是可以优化的!有机会就补充上。

Note:注意数组越界问题,即for循环中要不要减一什么的,我还不是很清楚。


参考:
1:王道--《数据结构》
2、《算法导论》
3、百度百科
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VFP中实现选择排序 时间:2009-06-07来源:编程入门网 作者:老马   众所周知在常用的简单排序方法中,前文所介绍的起泡排序(冒泡排序)是效率最差的一个了。我们今天所介绍的这个选择排序也是简单排序中的一种,不过比起泡排序的效率要高,并且也比较容易实现。   这些常用的排序方法多见诸于C/C++方面的资料中,如果要在vfp中实现这些排序方法,原理是一样的,只是在代码实现上略有差别。例如,在C/C++中数组的下标是从0开始,而vfp中数组的下标是从1开始;C/C++中的for语句可以采用for(i=0;i<n;i++)这种形式来同时完成变量赋初值、变量终值判断、变量递增这些操作,而vfp的for语句则有些弱,它的变量终值不能采取i<n这种形式来界定一个范围。因为以上的区别,在VFP中书写代码时要特别注意数组下标问题及循环变量的初值及终值,在以后的文章中不会再特别提及这些问题。   我们先看一下选择排序的基本思想和排序过程。(此部分内容引用自百度百科:http://baike.baidu.com/view/547263.htm)   基本思想   每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。   选择排序是不稳定的排序方法。n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:    ①初始状态:无序区为R[1..n],有序区为空。    ②第1趟排序   在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。   ……    ③第i趟排序   第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R(1≤i≤n-1)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。   这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。   排序过程   【示例】:    初始关键字 [49 38 65 97 76 13 27 49]   第一趟排序后 13 [38 65 97 76 49 27 49]   第二趟排序后 13 27 [65 97 76 49 38 49]   第三趟排序后 13 27 38 [97 76 49 65 49]   第四趟排序后 13 27 38 49 [49 97 65 76]   第五趟排序后 13 27 38 49 49 [97 65 76]   第六趟排序后 13 27 38 49 49 65 [97 76]   第七趟排序后 13 27 38 49 49 76 [97 76]   最后排序结果 13 27 38 49 49 76 76 97   知道这个排序方法的基本思想和排序过程,在vfp中书写代码就简单了,只是需要注意vfp中数组的下标及循环变量的初值及终值与C/C++的区别。实例的运行界面如下图:   本例依然采取生成10个随机整数的方式取得数据,然后用选择法对这10个整数进行从小到大的排序。实现过程:   一、新建表单,向表单添加一个编辑框控件及三个命令按钮,按上图设置这三个命令按钮的caption属性。   二、添加代码:   1.“生成10个随机整数”按钮的click事件: public s(10) for i=1 to 10 s(i)=int(rand()*100) &&产生两位数的随机整数 thisform.edit1.value=thisform.edit1.value+str(s(i),5) endfor   2.“清屏”按钮的click事件:thisform.edit1.value=""   3.“选择排序”按钮的click事件: local i,j,k,t as integer for i=1 to 9 k=i for j=i+1 to 10 if s(j)<s(k) k=j endif endfor t=s(k) s(k)=s(i) s(i)=t endfor thisform.edit1.value="" for i=1 to 10 thisform.edit1.value=thisform.edit1.value+str(s(i),5) endfor
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值