数据结构--排序

参考【算法】排序算法之希尔排序 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/122632213

1. 排序的定义

2. 插入排序

2.1 直接插入排序

在插入第i(i>1)个记录时,前面的i-1个记录已经排好序

void insertSort(int r[],int n)
{for(int i=2;i<=n;i++){if(r[i]<r[i-1]{r[0]=r[i];j=i-1;while(r[0]<r[j]){r[j+1]=r[j];j=j-1;}r[j+1]=r[j];j=j-1;}r[j+1]=r[0];}}
}

2.2 折半插入排序

用折半查找方法确定插入位置的排序

3. 希尔排序

缩小增量,多遍插入排序

基本思想:

将整个待排序记录分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列中的记录基本有序时,对全体记录进行直接插入排序。

分割待排序记录目的:

1.减少待排序记录

2.使整个序列向基本有序发展

希尔排序的特点:

1.一次移动,移动位置较大,跳跃式地接近排序后的最终位置

2.最后一次只需要少量移动

3.增量序列必须是递减的,最后一个必须是1

4.增量序列应该是互质的

示例图:

假设有一组{9, 1, 2, 5, 7, 4, 8, 6, 3, 5}无需序列。

第一趟排序: 设 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。接下来,按照直接插入排序的方法对每个组进行排序。
第二趟排序:
将上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 2 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为2组。按照直接插入排序的方法对每个组进行排序。
第三趟排序:
再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为1的元素组成一组,即只有一组。按照直接插入排序的方法对每个组进行排序。此时,排序已经结束。

注:需要注意一下的是,图中有两个相等数值的元素5和5。我们可以清楚的看到,在排序过程中,两个元素位置交换了

代码实现

void shell_sort(int arr[], int len) {int gap, i, j;int temp;for (gap = len >> 1; gap > 0; gap >>= 1)for (i = gap; i < len; i++) {temp = arr[i];for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)arr[j + gap] = arr[j];arr[j + gap] = temp;}
}

算法评价

1.希尔排序的效率取决于增量值gap的选取,时间复杂度并不是一个定值。

2.开始时,gap取值较大,子序列中的元素较少,排序速度快,克服了直接插入排序的缺点;其次,gap值逐渐变小后,虽然子序列的元素逐渐变多,但大多元素已基本有序,所以继承了直接插入排序的优点,能以近线性的速度排好序。

3.最优的空间复杂度为开始元素已排序,则空间复杂度为 0;最差的空间复杂度为开始元素为逆排序,则空间复杂度为 O(N);平均的空间复杂度为O(1)

4.希尔排序并不只是相邻元素的比较,有许多跳跃式的比较,难免会出现相同元素之间的相对位置发生变化。比如上面的例子中希尔排序中相等数据5就交换了位置,所以希尔排序是不稳定的算法。

4. 起泡排序(冒泡排序

基本思想:

两两比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止。

反序:即排序顺序与排序后的次序正好相反

太经典的排序算法了,不多说

template<class T>
void BubbleSort(T arr[], int n) {for (int i = 1; i < n; i++) {           //共进行n - 1趟排序:从1到n-1,逐步缩小待排序列for (int j = n - 1; j >= i; j--) { //反向检测,检查是否逆序if(arr[j] > arr[j - 1]){     //发生逆序,交换元素的位置T temp = arr[j];arr[j] = arr[j - 1];T[j - 1] = temp;}}}
}

时间复杂度为O(n² )  

5.快速排序

基本思想:

首先选择一个轴值(即比较的基准),通过一趟排序将待排序记录分割成独立的两部分,前一部分记录的关键码均小于或等于轴值,后一部分的关键码均大于或等于轴值,然后分别对这两部分重复上述方法,直到整个序列有序。

选择轴值的方法:

1. 使用第一个记录的关键码

2. 选取序列中间记录的关键码

3. 比较序列中第一个记录、最后一个记录和中间记录的关键码,取关键码居中的作为轴值并调换到第一个记录的位置

4. 随机选取轴值

选取不同轴值的后果:

决定两个子序列的长度,子序列的长度最好相等。

递归处理

时间复杂度:O(n)O(logn),最坏O(n2)

空间复杂度:O(log2n),最坏O(n)

不稳定的排序方法

过程演示

题目

6.简单选择排序

图示

 

代码

void selectsort(int r[],int n)
{int i,index;for(i=1;i<n;i++){index=i;for(j=i+1;j<=n;j++)if(r[j]<r[index]) index=j;if(index!=i) r[i]<==>r[index];}
}

 时间复杂度O(n2)

稳定的排序方法

7.堆排序

减少关键码间的比较次数。查找最小值的同时找到较小值。

堆的定义

堆是具有一下性质的完全二叉树:每个结点的值都小或者等于其左右孩子结点的值(称为小根堆),或者每个结点的值都大于或等于其左右孩子结点的值(称为大根堆

·小根堆的根结点是所有结点的最小者

·较小结点靠近根结点,但不绝对

堆和序列的关系

基本思想

首先将待排序的记录序列构造成一个堆,此时,选出了堆中所有记录的最小者,然后将它从堆中移走,并将剩余的记录再次调整成堆,这样又找出了次小记录。以此类推,直到堆中只有一个记录。

 动图演示https://vdn6.vzuu.com/SD/3bb38dfe-236a-11eb-8039-a6caf32b14c9.mp4?pkey=AAUyrCY8VNkvMdMU1V6cmk2JYP4PY3XxcITCzTRSwUQMzfJJEGolTKO0ORqU97S6zQFMp3fpKyqia3U_GdbZhZe1&c=avc.0.0&f=mp4&pu=078babd7&bu=078babd7&expiration=1704189211&v=ks6icon-default.png?t=N7T8https://vdn6.vzuu.com/SD/3bb38dfe-236a-11eb-8039-a6caf32b14c9.mp4?pkey=AAUyrCY8VNkvMdMU1V6cmk2JYP4PY3XxcITCzTRSwUQMzfJJEGolTKO0ORqU97S6zQFMp3fpKyqia3U_GdbZhZe1&c=avc.0.0&f=mp4&pu=078babd7&bu=078babd7&expiration=1704189211&v=ks6

 

void sift(int r[],int k, int m)
{i=k;j=2*i;temp=r[i];//将筛选记录暂存while(j<=m) //筛选还没有进行到的叶子{if(j<m && r[j]<r[j+1]) j++;//左右孩子中较大者if(r[i]>r[j]) break;else{r[i]=r[j];i=j;j=2*i;}}
r[i]=temp;将筛选记录移到正确位置
}
void HeapSort(int r[],int n)
{for(i=n/2;i>=1;i--)//初建堆sift(r,i,n);for(i=1;i>n;i++){r[1]<==>r[n-1+i];//移走堆顶sift(r,1,n-i);//重建堆}
}

时间复杂度O(nlog2n)

空间复杂度O(1)

8.归并排序

归并:将两个或两个以上的有序表组合成一个新的有序表

时间复杂度O(nlog2n)

空间复杂度O(n) 

void Merge(int r[], int r1[], int s, int m, int t)
{i=s;j=m+1;k=s;while(i<=m && j<=t){if(r[i]<=r[j]) r1[k++]=r[i++];else r1[k++]=r[j++];}if(i<=m) while(i<=m)r1[k++]=r[i++];else while(j<=t)r1[k++]=r[j++];
}

9.基数排序

示例

10.排序算法的比较 

1.时间复杂度

2.空间复杂度

3.稳定性

4.平均的时间性能

5.待排序记录个数n的大小

6.关键码的分布

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

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

相关文章

循环依赖和三级缓存

循环依赖&#xff1a; 是指一个或多个Bean实例之间存在直接或简介的依赖关系&#xff0c;这种依赖关系构成了环形调用(类与类之间的依赖关系形成了闭环)。 循环依赖的表现形式 eg1: 自己依赖自己的直接依赖 eg2: 两个对象之间的直接依赖 eg3: 多个对象之间的间接依赖 Spirng 框…

Notepad++运行C语言输出乱码

方法一&#xff1a;编码-编码字符集-中文-GB2312 这时原程序中文会变成乱码&#xff0c;我是重新输入中文 重新编译执行即可 缺陷&#xff1a;重开一个程序有中文还是会显示乱码&#xff0c;需要重新设置编码&#xff0c;比较麻烦 方法二&#xff1a;设置-首选项-新建-右侧编…

IntelliJ IDEA 拉取gitlab项目

一、准备好Gitlab服务器及项目 http://192.168.31.104/root/com.saas.swaggerdemogit 二、打开 IntelliJ IDEA安装插件 打开GitLab上的项目&#xff0c;输入项目地址 http://192.168.31.104/root/com.saas.swaggerdemogit 弹出输入登录用户名密码&#xff0c;完成。 操作Comm…

Azure Machine Learning - 聊天机器人构建

目录 聊天机器人架构概述消耗成本环境准备打开开发环境部署和运行将聊天应用部署到 Azure使用聊天应用从 PDF 文件获取答案使用聊天应用设置更改答复行为 本文介绍如何部署和运行适用于 Python 的企业聊天应用示例。 此示例使用 Python、Azure OpenAI 服务和 Azure AI 搜索中的…

5D动感影院新奇体验丰富环境特效7D互动影院

5D动感影院太火啦&#xff01;凭借真实互动感、全视景高清屏幕、立体环绕音效、D打造新颖沉浸式观影体验&#xff0c;成为年轻人/家长/小朋友的新晋打卡聚集地&#xff0c;时刻上演着精彩绝伦的视觉盛宴&#xff01; 1、5D动感影院【硬件组成】&#xff1a;动感平台、金属银幕、…

【LabVIEW FPGA入门】FPGA中的数学运算

数值控件选板上的大部分数学函数都支持整数或定点数据类型&#xff0c;但是需要请注意&#xff0c;避免使用乘法、除法、倒数、平方根等函数&#xff0c;此类函数比较占用FPGA资源&#xff0c;且如果使用的是定点数据或单精度浮点数据仅适用于FPGA终端。 1.整数运算 支持的数…

设计模式—— 单例设计模式

单例设计模式 什么是单例模式 单例模式是一种对象创建型模式&#xff0c;使用单例模式&#xff0c;可以保证为一个类只生成唯一的实例对象。也就是说&#xff0c;在整个程序空间中&#xff0c;该类只存在一个实例对象。 为什么使用单例模式 在应用系统开发中&#xff0c;我…

指向未来: 量子纠缠的本质是一个指针

指向未来: 量子纠缠的本质是一个指针 概述基本概念理解量子纠缠PythonJavaC 理解波粒二象性PythonJavaC 理解量子隧穿理解宇宙常量PythonJavaC 概述 量子纠缠 (Quantum Entanglement) 是量子系统重两个或多个粒子间的一种特殊连接, 这种连接使得即使相隔很远, 这些粒子的状态也…

e2studio开发三轴加速度计LIS2DW12(3)----检测活动和静止状态

e2studio开发三轴加速度计LIS2DW12.3--检测活动和静止状态 概述视频教学样品申请源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback ()…

4D毫米波雷达——原理、对比、优势、行业现状

前言 4D 毫米波雷达是传统毫米波雷达的升级版&#xff0c;4D指的是速度、距离、水平角度、垂直高度四个维度。 相比传统 3D 毫米波雷达&#xff0c;4D 毫米波雷达增加了“高度”的探测&#xff0c;将第四个维度整合到传统毫米波雷达中。 4D毫米波雷达被视为未来车载雷达的一…

Redis 笔记一

概览 1.Redis核心数据存储结构 2.Redis底层String编码int&embstr&raw 3.Redis底层压缩列表&跳表&哈希表 4.Redis底层Zset实现压缩列表和跳表如何选择 5.基于Redis实现微博&抢红包&12306核心业务 辅助学习&#xff1a;Redis 教程 | 菜鸟教程 1.Redis为什…

macOS系统下载安装IDEA 操作流程

目录 第一步 进入官网&#xff0c;选择箭头指向的版本 第二步 下载完成后打开&#xff0c;拖动安装包安装​编辑 第三步 点击" project"&#xff0c;在JDK下拉框选择"Download JDK" 第四步 下载完成以后&#xff0c;点击右下角的Create按钮。 第一步 进…