[读书笔记]算法(Sedgewick著)·第二章.初级排序算法

本章开始学习排序算法

1.初级排序算法

先从选择排序和插入排序这两个简单的算法开始学习排序算法。选择排序就是依次找到当前数组中最小的元素,将其和第一个元素交换位置,直到整个数组有序。


 1 public static void sort(Comparable a[]){
2 int N = a.length;
3 for(int i = 0; i < N; i ++){
4 int min = i; //最小元素索引
5 for(int j = i + 1; j < N; j++){
6 if(less(a[j], a[min])) min = j;
7 }
8
9 exch(a, i, min);
10 }
11 }

而插入排序就像打poker一样,找到每个元素在小数组中的位置。


1     public static void sort(Comparable a[]){
2 int N = a.length;
3 for(int i = 1; i < N; i ++){
4 //将a[i]插入a[i-1]、a[i-2]、a[i-3]...之中
5 for(int j = i; j > 0 && less(a[j], a[j-1]); j--){
6 exch(a, j, j-1);
7 }
8 }
9 }

算法思路相当简单,而本节比较有趣的地方是可视化排序算法。我们就实现这个可视化。

我们分为三个步骤。第一步,将一个数组的元素(这里我们选用double数据类型)用长条表示,并依次罗列在屏幕上。第二步,按照各个算法的思路将有序数组排序,画出一张可视轨迹图。第三步,将轨迹图动画化。

接下来的重头戏是比较选择排序和插入排序。通过下图的例子,我们可以看出第i个元素都进行一次交换和N-1-i次比较。对于长度为N的数组,选择排序要进行N^2/2次比较和N次交换。

而对于插入排序呢?情况比选择排序复杂。最坏情况(完全逆序)下,需要~N^2/2次比较和~N^2/2次交换;而最好情况(已经顺序)下,需要N-1次比较和0次交换。就如同例子中第3次插入时,S、T已经是有序的了,所以不存在交换的需要。对于随机排序的数组,在平均情况下每个元素都可能向后移动半个数组的长度,因此交换总数是~N^2/4,而比较次数是交换次数加上一个额外的项(相比N^2,可以忽略)。

而排序前数组的倒置(比如E-A)个数越少,插入排序就越快。接下来我们用随机数组来比较两种算法。

重复一百次的1000个随机数排序比较结果:

重复一百次的10000个随机数排序比较结果:

最后,我们可以得出:对于随机数组,插入排序和选择排序的运行时间是平方级别的,两者之比是一个较小的常数(本机测试为1.3~1.4)。

希尔排序的思想是使数组中任意减个为h的元素有序,也就是将插入排序的元素移动距离由1改变为逐渐增大的h。


 1 public static void sort(Comparable a[]){
2 int N = a.length;
3 int h = 1;
4 while(h < N/3) h = 3*h + 1;
5 while(h >= 1){
6 for(int i = h; i < N; i++){
7 for(int j = i; j >= h && less(a[j], a[j-h]); j -= h){
8 exch(a, j, j-h);
9 }
10 }
11 h = h/3;
12 }
13 }

这么做的原因是因为部分有序数组更适合插入排序。那么,我们就比较一下这两种算法的执行速度。

[读书笔记]算法(Sedgewick著)·第二章.初级排序算法,布布扣,bubuko.com

时间: 2024-10-25 08:30:24

[读书笔记]算法(Sedgewick著)·第二章.初级排序算法的相关文章

算法手记(5)初级排序算法

排序是将一组对象按照一定的规则重新排列的过程.即使目前完全可以使用标准库中的排序函数,学习排序算法仍然有着较大意义:   排序算法的学习可以帮助你全面了解比较算法性能的方法: 类似的技术上能有效解决其他类型的问题: 排序算法通常是我们解决问题的第一步: 更重要的是这些算法都很经典,优雅和高效. 排序在商业数据处理分析和现代科学中占有重要的地位,其中快速排序算法被誉为20世纪科学和工程领域十大算法之一.今天我们要看的就是相对简单但很经典的初级排序算法,包括选择排序,插入排序及Shell排序. 准备

软件工程读书笔记(2)——第二章 软件过程

第二章 软件过程 软件工程的目标是在规定的时间和预算内开发出高质量软件. 软件项目失败的主要原因几乎与技术和工具没有任何关系,更多的是由于缺少过程规范,只有建立规范的软件开发过程,并持续不断地加以改进,才能管理和控制软件产品的质量. 一.软件过程的概念 1.任务思维与过程思维 软件发展的前期阶段:强调软件开发结果,忽略软件开发过程.(类似于黑盒子) Watts Humphery首先将过程管理的原则和思想引入软件开发过程中,将软件开发任务看做是一个可控的,可度量的和可改进的过程. 2.软件过程的定

读书笔记 - javascript 高级程序设计 - 第二章 在Html中使用JavaScript

1 <script>的6个属性 async  立即下载当前script标签的外部脚本 但不能影响别的 charset 没用了 defer  文档显示之后再执行脚本,只对外部脚本有效 language 没用了 src type 描述代码内容Mine类型 默认就是text/javascript 没什么用 2 在解释器对<script>元素内部的所有代码求值完毕以前 页面中的其余内容都不会被浏览器加载或显示 3 有两种script 嵌入式 外部引入式 在解析外部引入式的js文件时,页面的

[读书笔记]算法(Sedgewick著)·第一章(1)

到家放松之后就开始学习算法了,手里拿的是拿的是一本Robert Sedgewick的橙皮书<算法(第四版)>的.这本书与导论那本书的不同之处在于轻数学思想.重实现,也就是说这是一本很不错的基础编程书.拿来做书中的练习还是蛮不错的,封面说有50种算法哦.思维导图如下,就且学且更新吧. 1.基本编程模型 第一章开始讲述用程序实现算法的优点:程序是对算法精确.优雅和完全的描述:可以通过运行程序来学习算法的各种性质:可以在应用程序中直接使用这些算法.还有这种学习算法的缺点缺点:分离思想和实现细节的困难

读书笔记:计算机网络第7章:阻塞控制

这是我在Coursera上的学习笔记.课程名称为<Computer Networks>,出自University of Washington. 由于计算机网络才诞生不久,目前正在以高速在发展,所以有些旧的教材可能都已经跟不上时代了.这门课程在2013年左右录制,知识相对还是比较新的.覆盖了计算机网络中的各个协议层,从物理层到应用层都讲得非常仔细.学完这门课程之后对计算机网络会有比较深刻的了解. 概述 课程位置 关于传输层和网络层的上半部分 话题 阻塞就类似于显示生活中的堵车 阻塞CONGEST

【读书笔记】设计模式第五章:行为型模式

本文主要分析了模板方法模式.命令模式.责任链模式.策略模式.迭代器模式,介绍它们的定义.优缺点.使用场景,以及实例代码.为了深刻地理解设计模式,最重要的还是动手编写代码. 我参照书中的例程重新构想了一些更加生动.易于理解的例子,希望大家喜欢. 代码可以通过以下链接进行浏览: http://git.oschina.net/caipeichao/java-design-pattern 这些代码都经过编译运行,保证没有错误. 模板方法 定义 定义一个操作中的算法框架,而将一些步骤延迟到子类中 角色:抽

【读书笔记】设计模式第6章:行为型模式2

本文主要分析了中介者模式.观察者模式.备忘录模式.访问者模式.状态模式.解释器模式,介绍它们的定义.优缺点.使用场景,以及实例代码.为了深刻地理解设计模式,最重要的还是动手编写代码. 我参照书中的例程重新构想了一些更加生动.易于理解的例子,希望大家喜欢. 代码可以通过以下链接进行浏览: http://git.oschina.net/caipeichao/java-design-pattern 这些代码都经过编译运行,保证没有错误. 中介者模式 定义 也叫调停者模式 用一个中介对象来封装一系列同事

一维向量旋转算法 编程珠玑 第二章

看了编程珠玑第二章,这里面讲了三道题目,这里说一下第二题,一维向量旋转算法. 题目:将一个n元一维向量(例数组)向左旋转i个位置. 解决方法:书上讲解了5种方法,自己只想起来2种最简单方法(下面讲的前两种). 1.原始方法. 从左向右依次移动一位,对所有数据平移:这样循环i次,算法最坏时间复杂度达n^2.耗时不推荐. 2.空间换时间. 顾名思义,申请一个i长度的空间,把前i半部分放到申请空间中,再把后面的所有数据向左移动i个位置,最后把申请的空间中的数据放到后半部分.浪费空间,不推荐. 3.杂技

深入理解排序算法(一):初级排序算法

[本系列博文会对常见的排序算法进行分析与总结,并会在最后提供几道相关的一线互联网企业面试/笔试题来巩固所学及帮助我们查漏补缺.项目地址:https://github.com/absfree/Algo.由于个人水平有限,叙述中难免存在不清晰准确的地方,希望大家可以指正,谢谢大家:)] 一.概述 我们在日常开发中经常需要对一组数据对象进行排序,这里的数据对象不仅包括数字,还可能是字符串等抽象数据类型(Abstract Data Type).由于排序是很多其他操作(比如二分查找)能够高效进行的基础,因