排序算法初步——冒泡排序法

排序:
排序操作是算法学习中的经典部分。尽管很多语言中都已经提前实现了排序功能,直接提供了排序函数,对于初学者来说,学习各种排序算法的思想仍是十分必要的。

今天主要介绍三种算法:经典的冒泡排序、插入排序和选择排序。不过在此之前,先来看一下评估排序算法优劣的几个标准。

分析算法的方向:

  1. 排序算法的执行效率:

注意,这里的执行效率并不能简单的等同于分析时间复杂度。

(1)要考虑低阶、常数还有系数。通常情况下,我们分析的时间复杂度都是针对在输入数据非常大的情况,所以低阶、系数和常数都被忽略了。然而在实际的开发当中,对于较小的数据量的排序也是经常需要的,所以在评估使用哪种算法是也需要把这些考虑进来。

(2)最好情况、最坏情况和平均时间复杂度。由于原始数据的秩序不定,所以需要了解算法在各种情况下的执行情况。

(3)比较次数和交换次数。

  1. 排序算法的内存消耗,就是通过算法的空间复杂度来衡量。特别说一下原地排序:就是空间复杂度为O(1)的排序算法。

  2. 排序算法的稳定性:经过排序之后,相等的数据原有的先后顺序不变。尽管进行了排序,原数据序列被“打乱”,但是稳定性较高的算法仍然保存了原本序列生成时的一些信息(排序时比较的常常是数据的主键,而非主键信息之间的关系有时也具有使用价值,比如输入时间的的先后关系)。


冒泡排序法

所谓冒泡就是从序列的第一个元素开始,与序列中其他的元素一一比较(可能遍历整个数组),每次只比较相邻的两个元素,如果满足大小条件,则交换位置,然后再进行下一个数的比较。我们来看一下具体的实现。

public static void main(String args[]) {
 
    //等待被排序的数组
 
    int[] nums = {4,6,1,5,3,2};
 
    for(int i = 0; i<nums.length;++i) {
 
    //循环遍历的总轮次
 
    boolean flag = false;
 
    for(int j = 0;j<nums.length-i-1;++j) {
 
    /*j<nums.length-i-1
     * -1表示防止数组越界,因为当前数总是在与“下一个数”比较
     * -i表示去除已经比较完毕的较大的数*/
 
    if(nums[j]>nums[j+1]) {
 
    //交换位置
 
    int temp = nums[j];
 
    nums[j] = nums[j+1];
 
    nums[j+1] = temp;
 
    }
 
}
 
if(!=flag) break; //有关flag的两行等下会解释
 
    }
 
}
 

以第一遍历比较为例,解释一下这个操作究竟干了些什么:

数组的比较情况

容易得出一轮遍历比较只能得出一个“最大数”,让它“冒”到队伍末尾。第二层循环的意义在于能够一直紧盯着当前的较大值,让它找到合适的位置,找到之后在开始下一轮大循环。

(比如上例中nums [ j ] = 6,nums [ j + 1 ] = 1,交换位置后( + + j ),新的nums [ j ] = 6,再与nums [ j + 1 ] 进行比较,较大的值能被一直关注,直到找到最终位置)

让我们来分析一下这种算法:

1. 算法的内存消耗:

如果发生交换行为,程序只需要申请一个(常量级)变量,空间复杂度为 O(1),属于原地排序。

2. 算法的稳定性:

示例中,数值相等的情况下不进行交换,原有的顺序不受干扰。

3. 算法的执行效率:

最好情况当然就是初始序列就是顺序的,也就“不用排序了”。然而上述结论是由我们的眼睛观察得出的。对于计算机来说,还是要遍历数组。一开始我觉得flag两行是多余的,因为在绝大多数情况下没什么用。但是在最好情况下,它却能降低在最好的情况下时间复杂度。在这里简单解释一下两层循环的意义:内循环是为了"跟随",每次比较的都是针对一个数。外循环是为了找到下一个大数。如果没有发生交换"小循环",就说明没有"逆序"存在,也就是不需要交换,"跟随"没有发生,序列无需再次寻找所谓"下一个大数"。

如果没有这样的判断,在一切情况下两层循环都会执行,复杂度为O(n^2);现在添加了判断,在最好情况下就只有里层循环执行,复杂度为O(n)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 排序算法几种分类方式: 1,稳定排序和不稳定排序 如果a==b, 当排序之前a在b的前面,排序后,a仍然在b...
    fly_ever阅读 403评论 0 0
  • 转载自:https://egoistk.github.io/2016/09/10/Java%E6%8E%92%E5...
    chad_it阅读 973评论 0 18
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,164评论 0 52
  • 清风明月升,同事夜相聚。 蒜蓉小龙虾,清汤大碗面。 啤酒频频开,笑脸张张艳。 丹丹靥若霞,芬芬肤如雪。 静静羞且娇...
    飞哥判案阅读 347评论 0 3
  • 加拿大温哥华是一座建在大海边,森林里的城市。 温哥华最有名的海滩,就是英吉利湾海滩。英吉利湾的沙滩紧挨着城市中心区...
    娇娇猫阅读 573评论 5 14