【Algorithms 4】算法(第4版)学习笔记 04 - 2.1 初级排序算法

文章目录

    • 前言
    • 参考目录
    • 学习笔记
      • 1:前置说明
      • 1.1:全序关系
      • 1.2:Comparable API 实现 demo
      • 1.3:排序算法模板
      • 2:选择排序
      • 2.1:内循环实现过程拆解
      • 2.2:代码实现
      • 2.3:特点
      • 3:插入排序
      • 3.1:内循环实现过程拆解
      • 3.2:代码实现
      • 3.3:最好的情况与最坏的情况
      • 3.4:部分有序数组
      • 4:希尔排序
      • 4.1: 增量选择
      • 4.2:代码实现
      • 4.3:补充:Knuth 增量 3x+1 的证明

前言

完成了第一章的基础学习之后,终于迎来了第二章的排序相关算法的学习。本文主要是对章节 2.1 初级排序算法的整理总结,主要包括 选择排序插入排序 以及 希尔排序

值得注意的是,Sedgewick 教授还讲了两节排序的应用:洗牌和凸包算法,但是我掌握得不太好,就不再本文进行说明了,感兴趣的朋友建议移步视频自行学习总结。

参考目录

  • B站 普林斯顿大学《Algorithms》视频课
    (请自行搜索。主要以该视频课顺序来进行笔记整理,课程讲述的教授本人是该书原版作者之一 Robert Sedgewick。)
  • 微信读书《算法(第4版)》
    (本文主要内容来自《2.1 初级排序算法》)
  • 官方网站
    (有书本配套的内容以及代码)

学习笔记

注1:下面引用内容如无注明出处,均是书中摘录。
注2:所有 demo 演示均为视频 PPT demo 截图。

1:前置说明

在正式讲解具体的排序算法前,先整理几个相关的概念知识,旁边后续深入。

1.1:全序关系

首先根据 Comparable 接口提出了 全序关系 这一概念,主要有三个特性:

(截图自视频 PPT)
在这里插入图片描述

注:在教授的 PPT 里面提出的三个特性分别是:反对称性、传递性和总体性。
但是在官方网站以及书本中我找到的特性分别是:自反性、反对称性和传递性,这里以后者为准。

在这里插入图片描述

(截图自官网)
在这里插入图片描述
可以看到,官网的描述与书本一致。

1.2:Comparable API 实现 demo

以时间作为一个常见的有序的对象实现了 Comparable 接口。

edu.princeton.cs.algs4.Date

在这里插入图片描述

edu.princeton.cs.algs4.Date#compareTo

在这里插入图片描述

1.3:排序算法模板

基于前面的 Comparable API,提出了一个排序算法模板,主要包含了 比较对象 的方法 less()交换对象 的方法 exch() ,这两个方法用于操作数据。

方法如下(来自官网):

private static boolean less(Comparable v, Comparable w) {return (v.compareTo(w) < 0);
}
private static void exch(Comparable[] a, int i, int j) {Comparable swap = a[i];a[i] = a[j];a[j] = swap;
} 

2:选择排序

在这里插入图片描述

光看字有点难一下子看明白,来结合教授的 PPT 理解。

2.1:内循环实现过程拆解

(截图自视频 PPT)
在这里插入图片描述

实际上最核心的步骤已经展示出来了,即:需要找到后侧未排序的集合中的最小值进行交换

2.2:代码实现

edu.princeton.cs.algs4.Selection#sort

在这里插入图片描述

2.3:特点

总结一下选择排序两个特点:

  • 运行时间和输入无关。(平方级别,如果数组一部分已经排好序了,对选择排序时间上没有影响,还是要一遍遍进行扫描。)
  • 数据移动是最少的。(线性级别

3:插入排序

上面的选择排序只和最小的(包括自己)进行交换 —— 对右侧操作,而插入排序则是和已经排序好的部分进行交换 —— 对左侧操作

3.1:内循环实现过程拆解

(截图自视频 PPT)
在这里插入图片描述

3.2:代码实现

edu.princeton.cs.algs4.Insertion#sort

在这里插入图片描述

3.3:最好的情况与最坏的情况

对于插入排序,不同情况下的数组排序情况有所不同。

最好的情况是:
需要 N-1 次比较和 0 次交换
有序数组,只需要证明后一个值比前一个值大,不需要进行交换。

最坏的情况是:
需要~N2/2 次比较和~N2/2 次交换
逆序数组,且不存在重复值,每个元素都需要移动到数组开头的位置。

3.4:部分有序数组

在这里插入图片描述

4:希尔排序

希尔排序是基于插入排序的一种快速排序算法。

希尔排序的思想是使数组中任意间隔为h的元素都是有序的。这样的数组被称为h有序数组。换句话说,一个h有序数组就是h个互相独立的有序数组编织在一起组成的一个数组。
……
实现希尔排序的一种方法是对于每个h,用插入排序将h个子数组独立地排序。

》

在这里插入图片描述

4.1: 增量选择

希尔排序的关键在于增量序列的选择。

透彻理解希尔排序的性能至今仍然是一项挑战。实际上,算法2.3是我们唯一无法准确描述其对于乱序的数组的性能特征的排序方法。

教授在 PPT 中列举了几项常见的增量序列:

(截图自视频 PPT)
在这里插入图片描述

对于上面的几种增量序列,教授进行了简单的说明:

  • Shell - 2N:在 1-sorted 前不会将偶数位置的元素和奇数位置的元素进行比较,性能很差。
  • Hibbard - 2N-1:不错。
  • Knuth - 3x+1( 1/2(3k-1) ):容易实现。
  • Sedgewick :根据奇数和偶数分别使用不同增量。(经过(教授本人)大概一年的研究得出的增量序列,性能不错,但无法得知是否是最好的)

当然,维基百科 上有更加详细的增量序列表:

(截图自维基百科)
在这里插入图片描述

4.2:代码实现

edu.princeton.cs.algs4.Shell#sort

在这里插入图片描述

4.3:补充:Knuth 增量 3x+1 的证明

实际上,Knuth 增量序列的增量为 1/2(3k-1),不过在代码中使用了 while 循环来找出最大增量(大于 N/3,N为总长度),然后再通过 h /= 3 来缩短增量。

来做一下计算,证明:
3 k − 1 2 ∗ 3 + 1 = 3 k + 1 − 1 2 \frac{3^k-1}{2}*3+1=\frac{3^{k+1}-1}{2} 23k13+1=23k+11

从左边开始展开计算:
3 k − 1 2 ∗ 3 + 1 \frac{3^k-1}{2}*3+1 23k13+1
拆解合并常数项得:
3 2 ∗ 3 k − 3 2 + 1 = 3 2 ∗ 3 k − 1 2 \frac{3}{2}*3^k-\frac{3}{2}+1 = \frac{3}{2}*3^k-\frac{1}{2} 233k23+1=233k21
利用指数的乘法规则:
3 ∗ 3 k = 3 k + 1 3*3^k=3^{k+1} 33k=3k+1
最终化简得:
3 k + 1 − 1 2 \frac{3^{k+1} - 1}{2} 23k+11

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/663424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【kubernetes】集群网络(二):Flannel的VxLan、Host-GW模式

文章目录 1 Pod的IP地址的分配2 CNI3 Flannel3.1 Flannel的安装3.2 VxLan3.3 Host-GW 4 总结 1 Pod的IP地址的分配 当节点上只安装了docker&#xff0c;则会用veth pairdocker0实现单个节点上容器之间的通信&#xff0c;并且这些容器都在同一个IP段&#xff0c;如果不修改&…

(2024,SaFaRI,双三上采样和 DFT,空间特征和频率特征)基于扩散模型的图像空间和频率感知恢复方法

Spatial-and-Frequency-aware Restoration method for Images based on Diffusion Models 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 3. 方法 3.1 修改数据保真度 3.2 …

JMeter GUI:测试计划和工作台

什么是测试计划&#xff1f; 测试计划是您添加 JMeter 测试所需元素的地方。 它存储运行所需测试所需的所有元素&#xff08;如线程组、计时器等&#xff09;及其相应的设置。 下图显示了测试计划的示例 测试计划是您添加 JMeter 测试所需元素的地方。 它存储运行所需测试…

Modbus协议学习第六篇之基于libmodbus库的示例程序(可以联合Modbus模拟仿真软件进行调试)

前置工作 学了这么多Modbus的知识&#xff0c;如果不进行实际的操作&#xff0c;总感觉懂的不透彻。基于此&#xff0c; 本篇博文就带各位读者来了解下如何通过编写程序来模拟与Modbus Slave仿真软件的通讯。当然了&#xff0c;这里有两个前提&#xff0c;如下&#xff1a; 1.请…

【深度强化学习】Python:OpenAI Gym-CarRacing 自动驾驶 | 提供项目完整代码 | 车道检测功能 | 路径训练功能 | 车辆控制功能

💭 写在前面:本篇是关于 OpenAI Gym-CarRacing 自动驾驶项目的博客,面向掌握 Python 并有一定的深度强化学习基础的读者。GYM-Box2D CarRacing 是一种在 OpenAI Gym 平台上开发和比较强化学习算法的模拟环境。它是流行的 Box2D 物理引擎的一个版本,经过修改以支持模拟汽车…

一键部署幻兽帕鲁服务器免费一年方案

一、背景介绍 简单讲一下历程&#xff0c;幻兽帕鲁从在1月19日上线&#xff0c;24小时内在线人数峰值便突破200万&#xff0c;作为2024年第一款现象级游戏&#xff0c;《幻兽帕鲁》上线后&#xff0c;由于人数太多&#xff0c;频现服务器过载导致游戏卡顿掉线的情况。为了能够…

【GitHub项目推荐--大语言模型课程】【转载】

Large Language Model Course Large Language Model Course&#xff08;大型语言模型课程&#xff09;是一个开源项目&#xff0c;该课程分为三个部分&#xff1a; LLM 基础&#xff1a;涵盖了数学、Python 和神经网络的基础知识。 LLM 科学家&#xff1a;专注于学习如何使用…

Linux调优相关命令汇总

Linux调优相关命令汇总 TIPS 本文基于CentOS 7编写&#xff0c;理论支持所有所有版本Linux发行版&#xff0c;部分命令的个别参数在不同版本中可能存在细微的差异。 入门级 # 切换目录 cd # 示例 # 切换到上一层目录 cd .. # 切换到/opt/software cd /opt/software# 显示工作目…

【机器学习】基于K-近邻的车牌号识别

实验四: 基于K-近邻的车牌号识别 1 案例简介 ​ 图像的智能处理一直是人工智能领域广受关注的一类技术&#xff0c;代表性的如人脸识别与 CT 肿瘤识别&#xff0c;在人工智能落地的进程中发挥着重要作用。其中车牌号识别作为一个早期应用场景&#xff0c;已经融入日常生活中&…

LVGL部件7

一.图片部件 1.知识概览 2.函数接口 1.lv_img_set_pivot 在LVGL&#xff08;LittlevGL&#xff09;中&#xff0c;要设置图像对象的旋转中心点&#xff0c;可以使用 lv_img_set_pivot 函数。该函数的原型如下&#xff1a; void lv_img_set_pivot(lv_obj_t * img, lv_coord_…

Flask框架开发学习笔记《5》简易服务器代码

Flask框架开发学习笔记《5》 Flask是使用python的后端&#xff0c;由于小程序需要后端开发&#xff0c;遂学习一下后端开发。 简易服务器代码 接口解析那一块很关键&#xff0c;学后端服务器这一块&#xff0c;感觉主要就是学习相应地址的接口怎么处理。 然后写清楚每个地址…

在centos 7 中安装配置Jdk、Tomcat、及Tomcat自启动

目录 一、安装配置Jdk 1.创建目录并上传文件 2.解压JDK压缩包 3.配置JDK环境变量 4.设置环境变量生效 二、安装配置Tomcat 1.上传Tomcat并解压 2.启停Tomcat 3.修改tomcat-user.xml配置 4.配置远程访问Tomcat 5.远程项目发布 三.Tomcat自启动配置 1.配置Tomcat自启…

链表的删除和预处理

创建空链表&#xff1a; struct Node head - - - 创建了头链表&#xff0c;内部不储存数据&#xff0c;地址为null&#xff0c;空间开在栈上&#xff08;在main函数里创建新的节点&#xff0c;一般都开在堆上&#xff09;。 函数不能返回局部变量的地址,因为局部变量的空…

各大厂急招鸿蒙开发员,争抢鸿蒙工程师

余承东宣布鸿蒙原生应用全面启动&#xff0c;华为开始了全面抛弃安卓的进程。 多家互联网公司也发布了鸿蒙OS的App开发工程师的岗位&#xff0c;开启了抢人大战。 有的企业开出了近百万的年薪招聘鸿蒙OS工程师&#xff0c;而华为甚至为鸿蒙OS资深架构师开出了100万-160万元的…

SASS 官方文档速通

前言&#xff1a;参考 Sass 中文网。 一. 特色功能 Sass 是一款强化 CSS 的辅助工具&#xff0c;在 CSS 语法的基础上增加了变量、嵌套、混合、导入等高级功能。有助于组织管理样式文件&#xff0c;更高效地开发项目。 二. 语法格式 .scss 拓展名&#xff1a;在 CSS3 语法的基…

二分图板子

原理&#xff1a; 匈牙利算法&#xff1a;二分图最大权匹配 - OI Wiki 简单说就是挨个找&#xff0c;找到就退出。后面的来了就让前面的挪位置。 板子&#xff1a; book指给u找位置时&#xff0c;有人考虑过的位置就不考虑了。 match[ i ]就是i位置对应的人。 e是关系 …

k8s helm安装Tiller出错解决

安装Helm 安装Helm通常使用一下命令&#xff1a; [rootk8s-master ~]# curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent …

Kotlin快速入门系列10

Kotlin的委托 委托模式是常见的设计模式之一。在委托模式中&#xff0c;有两个对象参与处理同一个请求&#xff0c;接受请求的对象将请求委托给另一个对象来处理。与Java一样&#xff0c;Kotlin也支持委托模式&#xff0c;通过关键字by。 类委托 类的委托即一个类中定义的方…

Mysql-ReadView + MVCC-RR 与 RC

实验准备 创建脚本 CREATE TABLE user (id int(11) NOT NULL AUTO_INCREMENT,name varchar(16) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,age int(11) NULL DEFAULT NULL,addr varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,PRIMARY …

1967 - 输出字符的ascii码

题目 从键盘读入一个字符&#xff0c;请计算并输出该字符的 ascii 码。 比如&#xff1a;字符 A 的 ascii 码输出是 65 &#xff0c;a 的 ascii 码输出是 97 &#xff0c;0 的ascii码输出是 48 。 输入 一个字符。 输出 一个整数&#xff0c;代表字符对应的 ascii 码。 …