根据学堂在线TsinghuaX: 30240184X 数据结构(2015秋)这门课的内容,对bubblesort做了一些总结。

1. bubblesort(起泡排序),原理来自这样一个观察规律:若序列有序,则任意一对相邻元素顺序。其逆否命题为:若存在相邻元素逆序,则序列无序。

2. 利用这一原理,bubblesort按照逐步消除逆序对的思路来实现整体有序。

3. 实现:对序列进行若干趟扫描,每遇到相邻逆序对,交换之,直至不再存在逆序对。

4. 算法的正确性分析:

(1)不变性(问题已求解的部分扩大):每一轮扫描交换,都会使当前未就位的元素中最大的那个就位(每次冒出一个最大的泡)

(2)单调性(问题未求解的规模递减):每一轮扫描交换,都会使有序序列长度增1,无序序列长度减1,问题规模也因而减1

5. 实现为如下代码:

 void swap(int& a,int& b){
int t=a;
a=b;
b=t;
} void bubblesort(int a[],int n){
bool sorted = false; //先假设尚未整体有序
while(!sorted){ //进入循环体
sorted=true; //假设现在前n项已有序
for(int i=; i<n-; i++){ //进行一趟扫描交换(从0一直到n-1,判断每组相邻元素)
if(a[i] > a[i+]){
swap(a[i],a[i+]);
sorted = false; //这一趟有交换则还需要再一趟扫描
}
}
n--;//一趟扫描交换必然会冒出一个泡~所以后面已就位的元素可以不在下次的扫描范围内了
}
}

6. 复杂度分析:

(1)基本语句为第12行的if(a[i]>a[i+1])

(2)初始时,必然会进入第9行的while循环,然后进入第11行的for循环,基本语句被执行n-1次。

(3)最好情况是输入完全有序,while循环只进入一次,for循环执行n-1轮,因此基本语句相应地执行n-1次,T(n) = n-1=Ω(n)

(4)最坏情况是输入完全逆序,while循环被执行n次;在第 i 轮while循环中,for循环执行 i 轮,基本语句也相应地执行 i 次。因此基本语句累加执行n(n-1)/2次,T(n)=n(n-1)/2=O(n2)

Vector一章,对bubblesort有两次常数优化。

函数原型是这样的:

  void bubble(Rank lo, Rank hi);

  void bubbleSort(Rank lo, Rank hi);

Rank即向量元素的秩,在此被定义为int型。lo和hi为待排序区间的左、右界桩。

外部通过调用 v.bubbleSort(lo, hi) 来给向量v的区间[lo,hi)排序,而bubbleSort调用bubble(lo,hi)实现对每个无序子区间的收缩。

最朴素的bubblesort大概是这样,最好最坏平均情况都为O(n^2)

 //最朴素版
void bubble(Rank lo, Rank hi) {
while (++lo < hi){//从左至右扫描,修正相邻逆序对
if (_elem[lo - ]>_elem[lo]){
swap(_elem[lo - ], _elem[lo]);
}
}
}
void bubbleSort(Rank lo, Rank hi){
while (lo < hi) bubble(lo, hi--);//右界桩每次向左挪一位
}

第一次改进后是这样,这种改进很常见,能使最好情况变为为O(n)。

 bool bubble(Rank lo, Rank hi) {
bool sorted=true;//增设sorted变量,记录此次扫描是否发生交换(未发生交换则sorted=true)
while (++lo < hi){
if (_elem[lo - ]>_elem[lo]){
sorted = false;
swap(_elem[lo - ], _elem[lo]);
}
}
return sorted;//返回是否已有序
}
void bubbleSort(Rank lo, Rank hi){
while (!bubble(lo, hi--));//一趟扫描没有发生交换(检测结果为sorted)则排序完成
}

第二次改进后是这样,可以跳跃式地收缩区间,降低了平均情况常数因子

 Rank bubble(Rank lo, Rank hi) {
Rank last=lo;//设置last变量,记录最后一次交换的位置
while (++lo < hi){;} swap(_elem[lo - ], _elem[lo]);
if (_elem[lo - ]>_elem[lo]){
last = lo
}
return last;//last及以后的元素都已就位,不必再进行扫描
}
void bubbleSort(Rank lo, Rank hi){
while (lo<(hi=bubble(lo, hi--)));//将右界桩挪到最后一次last位置
}

第二次改进可用下图来描述

【DSA MOOC】起泡排序的原理及常数优化的更多相关文章

  1. 回调函数及数组中sort()方法实现排序的原理

    1.回调函数:把一个方法A当一个参数值传递到另外一个函数B中,在B执行的过程当中我们随时根据需求让A方法执行:   什么是回调 :它是异步编程基本的方法,需要异步处理的时候一般采用后续传递的方式,将后 ...

  2. Java基础知识强化之集合框架笔记47:Set集合之TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序:Comparator)

    1. 比较器排序(定制排序) 前面我们说到的TreeSet的自然排序是根据集合元素的大小,TreeSet将它们以升序排列. 但是如果需要实现定制排序,比如实现降序排序,则要通过比较器排序(定制排序)实 ...

  3. Java基础知识强化之集合框架笔记44:Set集合之TreeSet保证元素唯一性和自然排序的原理和图解

    1. TreeSet保证元素唯一性和自然排序的原理和图解 2. TreeSet唯一性以及有序性底层剖析: 通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法. 跟踪 ...

  4. 起泡排序(Bubble sort)

    局部有序和整体有序 在由一组整数组成的序列A[0, n-1]中,满足 $ A[i - 1] \leq A[i] $ 的相邻元素称为顺序的:否则是逆序的. 扫描交换 由有序序列的特征,我们可以通过不断改 ...

  5. 内部排序->交换排序->起泡排序

    文字描述 首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序(L.r[1].key>L.r[2].key),则将两个记录交换位置,然后比较第二个记录和第三个记录的关键字.依次类推,直 ...

  6. 连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)

    连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort) 1,起泡排序(bubble sort),大致有三种算法 基本版,全扫描. 提前终止版,如果发现前区里没有发生交换 ...

  7. C语言 选择排序算法原理和实现 从数组中 找出最小的元素然后交换位置

    #include <stdio.h> int main(void) { /* 选择排序算法 原理:从数组中 找出最小的元素然后交换位置: */ int a[10] = {9,5,10,7, ...

  8. Python实现的选择排序算法原理与用法实例分析

    Python实现的选择排序算法原理与用法实例分析 这篇文章主要介绍了Python实现的选择排序算法,简单描述了选择排序的原理,并结合实例形式分析了Python实现与应用选择排序的具体操作技巧,需要的朋 ...

  9. php面试专题---Mysql索引原理及SQL优化

    php面试专题---Mysql索引原理及SQL优化 一.总结 一句话总结: 注意:只写精品 1.为表设置索引要付出代价 是什么? 存储空间:一是增加了数据库的存储空间 修改插入变动索引时间:二是在插入 ...

随机推荐

  1. 2014第3周六升级win8.1

    今天上班主要是沟通了一个需求,然后思考下实现方案并记录下要点,晚上没有加班就回来,把操作系统升级到了win8.1,升级的重要原因是,原来的win7时常会卡顿,并且开关机慢,还有上面装了很多无用的影响效 ...

  2. JS Message 网页消息提醒

    JS message是一个非常小的(用gzip压缩之后才3kb)JavaScript library 用于轻松在网页上展示通知提醒.除了通知,它还支持创建带风格的对话框和确认对话框.不需要任何JS框架 ...

  3. Kth Largest Element in an Array 解答

    Question Find the kth largest element in an unsorted array. Note that it is the kth largest element ...

  4. Bring Your Charts to Life with HTML5 Canvas and JavaScript

    Bring Your Charts to Life with HTML5 Canvas and JavaScript Bring Your Charts to Life with HTML5 Canv ...

  5. NicEdit - WYSIWYG Content Editor, Inline Rich Text Application

    NicEdit - WYSIWYG Content Editor, Inline Rich Text Application By calling the nicEditors.allTextarea ...

  6. Android ScrollView用法

    Android ScrollView用法 今天试着使用了一下Android的滚轮,以下是一个小小的测试,读取测试文件,主要是使用scrollTo函数和getScrollY(),程序点击BUTTON按钮 ...

  7. JS~JS里的数据类型

    JS里的数据类型,它虽然是个弱类型的语言,但它也有自己的规定的,它不会向其它语言那么,使用int来声明一个整形变量,而是使用 var,如果你是一个C#的开发者,你就会知道,原来C#现在也在和JS学,开 ...

  8. Winpcap网络编程九之Winpcap实战,ARP协议获得MAC表及主机通信

    大家好,本次我们须要完毕的任务是: 完毕两台主机之间的数据通信(数据链路层) 仿真ARP协议获得网段内主机的MAC表 使用帧完毕两台主机的通信(Hello! I'm -) 声明:本文章的目的是为大家的 ...

  9. Android应用程序请求SurfaceFlinger服务创建Surface的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7884628 前面我们已经学习过Android应 ...

  10. linux光盘、U盘的挂载与卸载

    mount [-t vfstype] [-o options] device dir1.-t vfstype 指定文件系统的类型,通常不必指定.mount 会自动选择正确的类型.关于一些常用的文件:i ...