《algorithms Unlocked》读书笔记3——计数排序
《Algorithms Unlocked》是 《算法导论》的合著者之一 Thomas H. Cormen 写的一本算法基础,算是啃CLRS前的开胃菜和辅助教材。如果CLRS的厚度让人望而生畏,这本200多页的小读本刚好合适带你入门。
书中没有涉及编程语言,直接用文字描述算法,我用 JavaScript 对书中的算法进行描述。
超越下界
之前的四个排序算法——选择排序、插入排序、归并排序、快速排序都是依赖于对排序关键字进行的比较。他们的决策依据都是“如果这个元素的排序关键字比另一个元素的排序关键字小,那么就进行相应操作,否则,进行其他操作或者什么也不做。”假如我们还是依赖这一规则,无论是简单或复杂的算法或者还没被发现的算法都无法突破这一下界(最坏情况下所需要的最小时间)。所以我们需要更改游戏规则,不让算法利用比较来进行排序。
计数排序
假设我们有一个数组,该数组内的元素都是 0~m-1 范围内的整数。例如 let array = [4, 1, 5, 0, 1, 6, 5, 1, 5, 3] 。如果我们可以知道排序关键字为 5 的元素有三个,并且刚好有 6 个元素的排序关键字小于 5,那么三个 5 应该位于位置6、7、8上。
首先我们要计算出有多少个元素的排序关键字等于某个值。比如有 3 个元素的排序关键字等于 5。
// m:定义了数组array中元素的取值范围 0~m-1
function countKeysEqual(array, m) {
// 创建一个空数组,长度为m,给每个元素赋值0
// 为什么要有这一步,万一哪个值array里没有就会变成NaN
let equal = [];
for (let i = 0; i < m; i++) {
equal[i] = 0;
};
for (let j = 0; j < array.length; j++) {
// 把array中的元素作为equal数组的索引值
// 该索引值在equal中对应的值为该元素在array中出现的次数
let key = array[j];
equal[key] += 1;
}
return equal;
}
接着我们计算出有多少个元素的排序关键字小于该值。比如有 6 个元素的排序关键字小于 5.
// equal 为上个函数返回的数组
function countKeysLess(equal, m) {
let less = [];
less[0] = 0;
for (let i = 1; i < m; i++) {
// less[i] = equal[0] + equal[1] + ... + equal[i - 1]
less[i] = less[i - 1] + equal[i - 1];
}
return less;
}
一旦得到less数组,我们就可以知道每个元素应该放在哪个位置。
// 根据less可以得知元素在数组中的位置
// 重排数组
function rearrange(array, less, m) {
let arrB = [];
for (let i = 0; i < array.length; i++) {
let key = array[i];
// 有几个小于key的元素排在key前面,则为key值在arrB中的索引
// 比如数组[0, 1, 1, 2],有3个排序关键字小于2,则2的索引为3
let index = less[key];
arrB[index] = array[i];
// 自增1,相同值的元素排在该值后一位
less[key] += 1;
}
return arrB;
}
把三个函数组合在一起构成计数排序。
// m:定义了数组array中元素的取值范围 0~m-1
function countSort(array, m) {
let equal = countKeysEqual(array, m);
let less = countKeysLess(equal, m);
let arrB = rearrange(array, less, m);
return arrB;
}
计数排序能够超越比较排序的下界,因为它从来不会对排序关键字进行比较。反之,它将排序关键字作为数组的索引,能进行这样的操作是因为排序关键字均是非常小的整数。如果排序关键字是带有分数的实数,或者是字符串,那么我们就不能使用计数排序了。
《algorithms Unlocked》读书笔记3——计数排序的更多相关文章
- 《Algorithms算法》笔记:元素排序(4)——凸包问题
<Algorithms算法>笔记:元素排序(4)——凸包问题 Algorithms算法笔记元素排序4凸包问题 凸包问题 凸包问题的应用 凸包的几何性质 Graham 扫描算法 代码 凸包问 ...
- 《Algorithms算法》笔记:元素排序(3)——洗牌算法
<Algorithms算法>笔记:元素排序(3)——洗牌算法 Algorithms算法笔记元素排序3洗牌算法 洗牌算法 排序洗牌 Knuth洗牌 Knuth洗牌代码 洗牌算法 洗牌的思想很 ...
- 算法笔记_129:计数排序(Java)
目录 1 问题描述 2 解决方案 2.1比较计数排序 2.2 分布计数排序 1 问题描述 给定一组数据,请使用计数排序,得到这组数据从小到大的排序序列. 2 解决方案 2.1比较计数排序 下面算法 ...
- 《Algorithms算法》笔记:元素排序(1)——简单排序
<Algorithms算法>元素排序(1)——简单排序 Algorithms算法元素排序1简单排序 排序问题 1 回调函数 2Java中回调函数的路线图 3 全序 4 Comparable ...
- 《Algorithm算法》笔记:元素排序(2)——希尔排序
<Algorithm算法>笔记:元素排序(2)——希尔排序 Algorithm算法笔记元素排序2希尔排序 希尔排序思想 为什么是插入排序 h的确定方法 希尔排序的特点 代码 有关排序的介绍 ...
- 《Algorithms Unlocked》读书笔记2——二分查找和排序算法
<Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础,算是啃CLRS前的开胃菜和辅助教材.如果CLRS的厚 ...
- 《Algorithms Unlocked》读书笔记1——循环和递归
<Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础. 书中没有涉及编程语言,直接用文字描述算法,我用 J ...
- 《Data-Intensive Text Processing with mapReduce》读书笔记之二:mapreduce编程、框架及运行
搜狐视频的屌丝男士第二季大结局了,惊现波多野老师,怀揣着无比鸡冻的心情啊,可惜随着剧情的推进发展,并没有出现期待中的屌丝奇遇,大鹏还是没敢冲破尺度的界线.想百度些种子吧,又不想让电脑留下污点证据,要知 ...
- OLAP与数据仓库------《Designing Data-Intensive Applications》读书笔记4
由于第三章的内容比较多,这里我们拆分成两篇读书笔记来记录.上一章我们聊了聊如何数据库是如何实现存储和检索的,今天这篇我们继续来看看OLTP与OLAP存储引擎的区别与联系. 1.OLTP与OLAP 联机 ...
随机推荐
- Power Designer如何批量改动数据类型
最近做项目的时候须要将OOM转换为PDM.在OOM中转换为PDM时,全部string的类型的属性都默认变为varchar(254),这可不是我们须要的类型,那么.如此多的类.如此多的属性.难道一个一个 ...
- 使用asyncsocket群聊
#import "ViewController.h" #import "AsyncSocket.h" @interface ViewController ()& ...
- mysql本地訪问linuxserver,出现SQLSTATE[HY000] [1130] Host '127.0.0.1' is not allowed to connect to this
解决方式:网上看了说.更改mysql库的user表,加入一条host为%的数据就能够.可是还是不行. 后来,直接登录mysql.给訪问加权限就能够了. 运行 [root@iZ25p77kem7Z ~] ...
- SSH中的免password登录
1:运行命令 ssh-keygen -t rsa 产生秘钥 ,位于~/.ssh目录下(假设在这期间有什么提示.一路敲击enter下去,什么都不用输入) 2:运行命令 cp ~/.ssh/id_rs ...
- win7中用 httplistener 出现 503 错误的问题
项目中须要用httplistener提供一个简单的httpserver服务.可是执行都是提示: UnHandledException Message:拒绝訪问 在System.Net.HttpList ...
- Creational模式之Builder模式
1.意图 将一个复杂对象的构建与它表示分离,使得相同的构建过程能够创建不同的表示. 查看很多其它请点击 2.别名 无 3.动机 一个RTF(Rich Text Format)文档交换格式的阅读器应能将 ...
- 以流方式读写文件:文件菜单打开一个文件,文件内容显示在RichTexBox中,执行复制、剪切、粘贴后,通过文件菜单可以保存修改后的文件。
MainWindow.xaml文件 <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&q ...
- redis主从配置+哨兵模式
1.搭建redis主从,一个master两个slave,加一个哨兵监听(sentinel),可以新建三个虚拟机,模拟环境,我的电脑没那么多虚拟机,就在一台虚拟机上弄的. 2.安装redis,如果是三台 ...
- jquery如此强大,为什么还要写原生呢?
这是一个伪标题,其实是一篇年终总结. 在这家公司一年多,蛮多收获的.大部分来自自己,小部分来自公司. 做前端开发到现在,我觉得可以分为两部分. 前半部分做项目用原生js,jquery以及各种基于jq的 ...
- 如何高效撤销Git管理的文件在各种状态下的更改
一.背景 企业中我们一般采用分布式版本管理工具git来进行版本管理,在团队协作的过程中,我们难免会遇到误操作,需要撤销更改的情况,那么我们怎么高效的进行撤销修改呢?对于还未提交到暂存区的代码怎么高效撤 ...