冒泡排序

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、百度百科
水仙花数的vfp实现 时间:2009-05-08来源:编程入门网 作者:老马   本文作者“老马”为编程入门网VFP专栏作家,转载请保留这句话。   记得看过朋友的文章中有句话大致是这个意思:一个人编程的水平与实现同一目的所需的代码数量成反比。其实这句话很有道理,如果用这个观点来评价我自己,我应该是一个苍老的菜鸟,我做出来的东西勉强可用,但代码在高手看来却是惨不忍睹。我所走过的轨迹与常人大概也有所不同:计算机专业科班的可能在毕业后从事coding多年之后,当感觉自己力不从心时转行做管理或教师;而我恰恰相反,外贸专业毕业后狂热地自学了一些东西,教了几年C语言、vb、vfp及asp等课程,几乎所有的业余时间都用到了接活来做上,这一点也差不多达到了狂热的程度。不过后来发现自己似乎是走进了死胡同:我试图走进VC的世界,可是被MFC、SDK这些东西折磨得痛苦之极;当我为自己开始能用asp做些东西而沾沾自喜的时候,一个强调代码与界面分离的asp.net一天比一天时髦起来,而它的身后是一个.NET家族。更新的技术何时出现?天知道,或许就在明天。我终于开始明白,我实际并不象身边的人说的那样聪明,我也只是一个平庸的人;我终于开始明白,如果在我所从事的这个没有任何保障的“挨踢”行业继续做下去,过几年我会成为40、50人员,那时恐怕连愿意为我交社保、医保的地方都找不到了。所以现在我进入了企业,不再是教师,因为这需要很大的精力来证明自己的能力和水平;也不再为了些“水票管理”之类的东西而通宵达旦,因为这样做得到的是几个小钱,失去的却是最宝贵的健康。   今天和几个高中同学小聚了一下,或许是人岁数大了愿意回忆从前的事,或许是还有些酒意,所以有了上面的这一段话。不过我想这不应该算是牢骚,应该说是一个菜鸟对自己的可笑经历的总结。   我始终认为C语言是一个基础性的语言,以前无论是VB或VFP课,我总会要求同学自己找本谭浩强的《C程序设计》,把预处理命令、指针、结构体与共用体等几部分内容pass过去,阅读其基础部分的内容;而在课时充足的情况下,我也会经常拿C程序书中诸如“鸡兔同笼”这样有趣的题来“折磨”一下班上的同学。   而现在有些日子了,有两个高中同学总跑到我家里来。人活到老、学到老,这本是件好事,不过我还是有些苦恼。因为他们到我家里来学习,不仅不交学费,我还得管他们饭。他们问到的vfp的东西比较多,所以我打算继续把这方面的一些东西翻出来晒晒。从本文开始会探讨一下C程序书中比较经典的几个算法在VFP中实现的问题,当然纯属菜鸟之见,有没有用那可两说,得自己去分析。觉得有用的话,或许可以开拓思路、扩充您的知识面,我很高兴;觉得没用的话,您权当我是吃撑了,您能忍受我罗嗦了这么长时间,我一样很高兴,呵呵。   水仙花数的实现是一个比较经典的算法题,今天我们首先在vfp中来实现它。   首先我们了解一下什么是“水仙花数”。所谓水仙花数是指一个n位数,其各位数字立方和等于该数本身的值,例如:153=13+53+33 ,所以153是一个水仙花数。   我们来做一个简单点儿的:求解3位数的水仙花数,即100至999之间的水仙花数。很明显这个程序需要使用循环,并且从水仙花数的概念可知,其重点是求解出循环变量当前值的各位数字的值。剩下的工作就简单了,把求解出的各位数字的立方和与循环变量当前值进行比较,如果相等则说明这是一个水仙花数,输出它即可。相关说明见代码注释。本文发表于编程入门网:www.bianceng.cn   我们用表单来实现这个例子,运行时如下图:   参照上图开始我们的制作:   一、新建表单,向表单上添加一个标签控件,caption属性值设置为“显示100到999间的水仙花数”;添加两个命令按钮command1和command2,并将它们的caption属性值分别设置为“开始”和“清除”;添加一个编辑框控件Edit1,属性值均采用默认的。   二、添加事件代码:   1、“清除”按钮的click事件: thisform.edit1.value="" thisform.refresh   2、“开始”按钮的click事件: local i,a,b,c for i=100 to 999 a=int(i/100) &&百位的值等于这个三位数除以100后取整 b=int((i-100*a)/10) &&用这个三位数减去它的百位数字与100乘积, &&对得到的差除以10后进行取整,结果就是十位的值 c=i-int(i/10)*10 &&与上面原理相同,这是求个位的值 if i=a^3+b^3+c^3 &&成立说明是水仙花数并输出 thisform.edit1.value=thisform.edit1.value+str(i,5)+chr(13) &&用chr(13)换行 endif endfor
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值