当前位置: 首页 > news >正文

排序《数据结构》

排序 《数据结构》

  • 1.排序的概念及其运用
    • 1.1 排序的概念
    • 1.2 排序运用
    • 1.3常见的排序算法
    • 1.4 排序动图演示
  • 2.常见排序算法的实现
    • 2.1 插入排序
    • 2.2希尔排序
    • 2.3 快排
      • 左边做keyi,右边先走,可以保证相遇位置比keyi小
    • 2.4 快速排序优化
      • 快排(非递归)
    • 2.6堆排序
    • 2.7 归并排序

1.排序的概念及其运用

1.1 排序的概念

1、排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
2、稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
3、 内部排序:数据元素全部放在内存中的排序。
4、外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不断地在内外存之间移动数据的排序。

1.2 排序运用

在这里插入图片描述

在这里插入图片描述

1.3常见的排序算法

在这里插入图片描述

1.4 排序动图演示

插入排序

void InsertSort(int* a,int n)//n为数组大小

在这里插入图片描述

希尔排序

void ShellSort(int* a,int n)//n为数组大小

在这里插入图片描述

选择排序

void SelectSort(int*a, int n);//n为数组大小

在这里插入图片描述

堆排序

voidAdjustDwon(int*a, int n, int parent);//向下调整
{
// 先假设左孩子小
int child = parent * 2 + 1;while (child < n)  // child >= n说明孩子不存在,调整到叶子了
{// 找出小的那个孩子if (child + 1 < n && a[child + 1] < a[child]){++child;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}
}
}
voidHeapSort(int*a, int n);

在这里插入图片描述

快排

void QuickSort(int* a,int n);

在这里插入图片描述

2.常见排序算法的实现

2.1 插入排序

基本思想:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,
直到所有的记录插入完为止,得到一个新的有序序列。

根据以上文字:
我们可以用(玩扑克牌来实例化)

在这里插入图片描述

当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移

插入排序特性总结:
1. 元素集合越接近有序,直接插入排序算法的时间效率越高
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1),它是一种稳定的排序算法
4. 稳定性:稳定

插入排序的实现

void InsertSort(int* a,int n)
{
for(int i=0;i<n-1;i++)//多趟
//一趟插入排序{
int end=i;
int tmp=a[end+1];
while(end>=0){if(a[end]>tmp){a[end+1]=a[end];end--;}elsebreak;//以防tmp是数组中最小的数}
a[end+1]=tmp;}}

2.2希尔排序

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

在这里插入图片描述

希尔排序的特性总结:1. 希尔排序是对直接插入排序的优化。2. 当gap > 1时都是预排序,目的是让数组更接近于有序。 当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
3.  希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定:大概是n^(1.3)

在这里插入图片描述

4. 稳定性:不稳定
void ShellSort(int* a,int n)
{
while(gap>1){// +1保证最后一个gap一定是1// gap > 1时是预排序// gap == 1时是插入排序int gap=(3/n)+1;//第一趟for(int i=0;i<n-gap;i++){int end=i;int tmp=a[end+1];while(end>=0){if(a[end]>tmp){a[end+1]=a[end];end-=gap;}elsebreak;}a[end+1]=tmp;}}}

2.3 快排

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

特点总结:

快速排序的特性总结:
快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
时间复杂度:O(N*logN)
空间复杂度:O(logN)
稳定性:不稳定

1、hoare版本
void QuickSort(int*a,int left,int right)
{if(right<=left){return ;}int begin=lef;int keyi=left;int end=right;while(begin<end){while(begin<end&&a[keyi]<=a[begin]){begin++;}while(begin<end&&a[keyi]>=a[end]){end--;}Swap(&a[begin],&a[end]);//交换
}
Swap(&a[begin],a[keyi]);
keyi=begin;
QuickSort(a,left,keyi-1);
QuickSort(a,keyi+1,right);
}

左边做keyi,右边先走,可以保证相遇位置比keyi小

相遇场景分析:
L遇R: R先走,停下来,那么R停下的条件是比keyi小的位置,
L没找到大的,遇到R停下来了

在这里插入图片描述

 R遇L:

在这里插入图片描述

那么我们可以得出:keyi在左边,R先走,keyi在右边,L先走

2、挖坑法

在这里插入图片描述
3、双指针表达法
在这里插入图片描述

代码实现:

int partSort1(int* a, int left, int right)//双指针排序法
{int prve = left;int cur = prve + 1;int keyi = left;while (cur <= right){if (a[keyi] < a[cur] && ++prve != cur){Swap(&a[prve], &a[cur]);cur++;}cur++;}Swap(&a[prve], &a[keyi]);return prve;
}
void QuickSort(int* a, int left, int right)
{if (left >= right){return;}if ((right - left + 1) < 10){insertSort(a + left, right - left + 1);}else{int keyi = partSort1(a, left, right);QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);}
}

2.4 快速排序优化

  1. 三数取中法选key
int order(int* a, int left, int right)
{int midi = (left + right) / 2;if (a[left] > a[midi]){if (a[midi] > a[right]){return midi;}else if (a[left] > a[right]){return right;}else{return left;}}else if(a[midi]<a[right]){return midi;}else{if (a[left] < a[right]){return right;}elsereturn left;}}
  1. 递归到小的子区间时,可以考虑使用插入排序
void insertSort(int* a, int n)
{for (int i = 0;i < n-1;i++){int end=i;int tmp = a[end+1];while (end >= 0){if (a[end] > tmp){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}
}void QuickSort(int* a, int left, int right)
{if (left >= right){return;}if ((right - left+1) < 10)//小区间优化{insertSort(a+left, right - left + 1);}else{int midi = order(a, left, right);Swap(&a[midi], &a[left]);int keyi = left;int begin = left, end = right;while (begin < end){while (begin < end && a[end] >= a[keyi]){--end;}while (begin < end && a[begin] <= a[keyi]){++begin;}Swap(&a[begin], &a[end]);}Swap(&a[begin], &a[keyi]);keyi = begin;QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);}
}

快排(非递归)

用栈来代替递归

 先把区间left和right入栈,然后分隔区间,在令分隔的右区间先入栈,左区间后入栈(因为栈后进先出的原则),那么弹出来的就是左区间下标,在对坐下标进行处理,每一次出栈都代表着区间排序,
等栈为空时,那么排序就完成了
void QuickSortNonR(int* a, int left, int right)
{
ST st;
STInit(&st);
STPush(&st, right);//进栈
STPush(&st, left);//进栈
while()
left = STTop(&st);
STPop(&st);
right= STTop(&st);
STPop(&st);
int begin = left;
int end = right;
int keyi = begin;
while (begin < end)//交换
{while (begin < end && a[end] >= a[keyi]){end--;}while (begin < end && a[begin] <= a[keyi]){begin++;}Swap(&a[begin],&a[end]);
}
Swap(&a[keyi], &a[begin]);keyi = begin;
// [left, keyi-1] keyi [keyi+1, right]
if (keyi + 1 < right ){STPush(&st, right);//右区间的右下标(入栈)STPush(&st, keyi + 1);//右区间的左下标(入栈)}if (left < keyi - 1){STPush(&st, keyi - 1);//左区间的右下标(入栈)STPush(&st, left);//左区间的坐下标(入栈)}}STDestroy(&st);
}

2.6堆排序

直接选择排序的特性总结:
堆排序使用堆来选数,效率就高了很多。
时间复杂度:O(N*logN)
空间复杂度:O(1)
稳定性:不稳定

实现代码:

void headsport(int* arr, int n)
{//时间复杂度O(N)for (int i = (n-1-1)/2;i >=0;i--){AdjustDown(arr,n,i);//向下调整建堆}int end = n - 1;//取最后一位数据while (end > 0)
{Swap(&arr[0], &arr[end]);//交换AdjustDown(arr, end, 0);//在向下建堆end--;}
}

2.7 归并排序

基本思想
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and
Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有
序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

在这里插入图片描述

特性总结:

 1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。2. 时间复杂度:O(N*logN)3.  空间复杂度:O(N)4.  稳定性:稳定

代码实现:

void _mergeSort(int* a, int* tmp ,int begin, int end)
{if (end-begin<1){return;}int mid = (begin + end) / 2;//如果[begin,mid-1],[mid,end]有序就归并_mergeSort(a, tmp, begin, mid);_mergeSort(a, tmp, mid+1, end);//归并int begin1 = begin;int begin2 = mid+1;int end1 = mid;int end2 = end;int i = begin;while (begin1<=end1&&begin2<=end2){if (a[begin1] < a[begin2]){tmp[i++] = a[begin1++];}elsetmp[i++] = a[begin2++];}while (begin1 <= end1){tmp[i++] = a[begin1++];}while (begin2 <= end2){tmp[i++] = a[begin2++];}memcpy(a+begin, tmp+begin,(end-begin+1)*sizeof(int));
}void mergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}_mergeSort(a, tmp, 0, n - 1);
}

排序部分结束啦!!!感谢大家观看

相关文章:

排序《数据结构》

排序 《数据结构》 1.排序的概念及其运用1.1 排序的概念1.2 排序运用1.3常见的排序算法1.4 排序动图演示 2.常见排序算法的实现2.1 插入排序2.2希尔排序2.3 快排左边做keyi&#xff0c;右边先走&#xff0c;可以保证相遇位置比keyi小 2.4 快速排序优化快排&#xff08;非递归&a…...

flutter 提示框2 Dialog

flutter 提示框 写在点击的方法体中 child里放自己喜欢的 showDialog( context: context, builder: (BuildContext context) { final Dialog alertDialog Dialog( backgroundColor: Colors.transparent,shadowColor:Colors.transparent,child: Container(height: mediawi…...

如何选择SDR无线图传方案

在开源软件定义无线电&#xff08;SDR&#xff09;领域&#xff0c;有几个项目提供了无线图传的解决方案。以下是一些开源SDR无线图传方案&#xff1a; 1. **OpenHD**&#xff1a;这是一个远程高清数字图像传输的开源解决方案&#xff0c;它使用SDR技术来实现高清视频的无线传…...

关于Python类中方法__init__()解析

# import numpy as npclass Car():def __init__(self, maker, name, year):self.maker makerself.name nameself.year yearprint(self.searchMakrt() "123")def searchMakrt(self):print("汽车制作厂家为&#xff1a; " self.maker)# passreturn &quo…...

微信小程序 自定义组件

1. 微信小程序 自定义组件 微信小程序支持组件化开发&#xff0c;这有助于我们复用代码&#xff0c;提高开发效率。下面我将给出一个简单的微信小程序组件化示例&#xff0c;包括一个自定义组件的创建和使用。 1.1. 创建自定义组件 首先&#xff0c;在项目的 components 目录…...

Mac+Pycharm配置PyQt6教程

安装包 pip install PyQt6 PyQt6-tools #查看Qt版本 pip show PyQt6 pip show pyqt6-tools 配置扩展工具 QTD(界面设计) Program&#xff1a;/Users/wan/PycharmProjects/NewDemo/venv/lib/python3.11/site-packages/qt6_applications/Qt/bin/Designer.app Working directo…...

如何保证Redis与Mysql双写一致性?

https://www.cnblogs.com/coderacademy/p/18137480 延迟双删 对于上面链接的文章&#xff0c;里面的延迟双删没有给出具体的例子&#xff0c;也没有直接指出具体解决的问题是针对那种缓存策略&#xff0c;这里补充一下&#xff0c;延时双删缓存针对的是Cache aside pattern(缓…...

9.8笔试记录

1.在c中哪些运算符不能重载? 在 C 中&#xff0c;有以下几个运算符不能被重载&#xff1a; . &#xff1a;成员访问运算符。例如obj.member中的.不能被重载。 :: &#xff1a;作用域解析运算符。用于指定命名空间、类等的作用域&#xff0c;不能被重载。 ?: &#xff1…...

SRE-系统管理篇

SRE-系统管理篇 进程管理 进程的概念: 运行起来的程序,命令,服务等等都可以称作进行,进程都是运行在内存当中的。 程序的概念: 一般指安装包,程序代码,应用它们存放在磁盘上面的。 守护进程的概念: 守护进程,一直运行的进程,也可以叫做服务。 进程的分类 僵…...

傅里叶级数,傅里叶变换

先读文章&#xff1a;傅里叶分析之掐死教程&#xff08;完整版&#xff09;更新于2014.06.06 - 知乎 (zhihu.com) 傅里叶级数 一、内容&#xff1a;每个周期性函数都可以表示为无穷多个不同频率的正弦函数的叠加。 二、公式&#xff1a; 三、从时域到频域所保留的三点信息&…...

零知识证明在BSV网络上的应用

​​发表时间&#xff1a;2023年6月15日 2024年7月19日&#xff0c;BSV区块链主网上成功通过使用零知识证明验证了一笔交易。 零知识证明是一种技术&#xff0c;它允许一方&#xff08;证明者&#xff09;在不透露任何秘密的情况下&#xff0c;向另一方&#xff08;验证者&…...

无任何门槛!3分钟5步,发布属于你的第一个智能体小程序,99%的人还不知道怎么用

相信大家都用微信小程序&#xff0c;但是大部分人应该还没有过属于自己的小程序吧。 今天程哥就带大家花三分钟用五步&#xff0c;来创建一个属于自己的微信小程序。 之前Coze在发布渠道里也有发布小程序的渠道&#xff0c;但是试过的人都知道&#xff0c;这个是有一定门槛的…...

怎么强制撤销excel工作表保护?

经常不是用的Excel文件设置了工作表保护&#xff0c;偶尔打开文件的时候想要编辑文件&#xff0c;但是发现忘记了密码&#xff0c;那么这种情况&#xff0c;我们怎么强制撤销excel工作表保护&#xff1f;今天分享两种解决方法。 方法一、 将excel文件转换为其他文件格式&…...

每天学习一个字符串类函数之memmove函数

目录 前言&#xff1a; 一、头文件 二、memmove函数的作用 三、理解memmove函数的定义 1、返回类型 2、参数 四、使用memmove函数 案例1&#xff1a; 案例2&#xff1a; 五、解决数据拷贝之前被覆盖的方法 六、模拟实现memmove函数 前言&#xff1a; 上一篇博客&#xff0c;我…...

【机器人工具箱Robotics Toolbox开发笔记(十三)】三自由度机器人圆弧轨迹规划仿真实例

在实际应用场景中,我们通常预先明确了目标末端的运动轨迹,随后引导机器人进行相应的动作。本实例具体展示了如何基于给定的两个点,计算出末端的精确位姿,并以此为基础,进一步规划出一条平滑的圆弧轨迹供机器人执行。这样的流程确保了机器人能够沿着预定的路径,精准且高效…...

软件工程-图书管理系统的概要设计

软件概要设计说明书 目录 软件概要设计说明书 一、引言 1.1 编写目的 1.2 背景 1.3 定义 1.3.1特定对象 1.3.2专业术语 1.4 参考资料 二、总体设计 2.1 需求规定 2.1.1信息要求 2.1.2功能要求 2.2 运行环境 2.3 基本概要设计和处理流程 2.4 体系结构设计 2.5 模…...

springboot 整合swagger

没有多余废话&#xff0c;就是干 spring-boot 2.7.8 springfox-boot-starter 3.0.0 结构 POM.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/…...

Flutter 进阶:绘制加载动画

绘制加载动画&#xff1a;由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类&#xff1a;LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态&#xff0c;而 Load…...

【深度学习】梯度下降法

梯度就是导数&#xff0c;而梯度下降法就是一种通过求目标函数的导数来寻找目标函数最小化的方法。梯度下降目的是找到目标函数最小化时的取值所对应的自变量的值&#xff0c;目的是为了找自变量X。 最优化问题在机器学习中有非常重要的地位&#xff0c;很多机器学习算法最后都…...

基于机器学习的电商优惠券核销预测

1. 项目简介 随着移动互联网的快速发展&#xff0c;O2O&#xff08;Online to Offline&#xff09;模式已成为电商领域的一大亮点。优惠券作为一种有效的营销工具&#xff0c;被广泛应用于吸引新客户和激活老用户。然而&#xff0c;传统的随机投放方式往往效率低下&#xff0c;…...

PHP-FPM 远程代码执行漏洞(CVE-2019-11043)复现

启动环境 切换目录到vulhub/php/CVE-2019-11043下 查看端口 访问 安装漏洞利用工具 git clone https://github.com/neex/phuip-fpizdam.git 安装go语言 # 1、下载go&#xff0c;这里使用 go1.22.5 版本&#xff0c;可替换为最新版本 wget https://dl.google.com/go/go1.22.5.…...

Rust : 从事量化的生态现状与前景

Rust适不适合做量化工作&#xff1f; 一般地认为&#xff0c;目前大部分场景策略开发最佳是Python&#xff1b;策略交易和部署是C。但还是有人会问&#xff0c;Rust呢&#xff1f; 这个问题不太靠谱&#xff01; 适不适合做一件事情&#xff0c;本身就是一件主观的事。即使是…...

Java项目——苍穹外卖(一)

Entity、DTO、VO Entity&#xff08;实体&#xff09; Entity 是表示数据库表的对象&#xff0c;通常对应数据库中的一行数据。它通常包含与数据库表对应的字段&#xff0c;并可能包含一些业务逻辑。 DTO&#xff08;数据传输对象&#xff09; 作用&#xff1a;DTO 是用于在…...

20240908 每日AI必读资讯

新AI编程工具爆火&#xff1a;手机2分钟创建一个APP&#xff01; - AI初创公司Replit推出的智能体——Replit Agent。开发环境、编写代码、安装软件包、配置数据库、部署等等&#xff0c;统统自动化&#xff01; - 操作方式也是极其简单&#xff0c;只需一个提出Prompt的动作…...

HNU-2023电路与电子学-实验3

写在前面&#xff1a; 本次实验是完成cpu设计的剩余部分&#xff0c;整体难度比上一次要小&#xff0c;细心完成就能顺利通过全部测评 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能&#xff0c;设计 8 重 3-1 多路复用器。 3.分析模型机的功能…...

html基础语法 看这一篇就够了!

HTML 一 概念 html:html 文件根标签 head:编写页面相关的属性 title:页面标题 body:页面内容展示信息 二 DOM 树&#xff1a; 所有的标签都是 html 的子标签 head 和 body 是兄弟标签&#xff0c;同一级别 head 和 title 为父子标签 1.第一个程序 <html><head>…...

【redis】redis的特性和主要应用场景

文章目录 redis 的特性在内存中存储数据可编程的扩展能力持久化集群高可用快 redis 的应用场景实时数据存储缓存消息队列 redis 的特性 redis 的一些特性&#xff08;优点&#xff09;成就了它 在内存中存储数据 In-memory data structures MySQL 主要是通过“表”的方式来…...

部署后端WebSocket服务到AWS云服务器

目录 1.创建AWS账户2.选择EC2实例3.配置EC2实例4.使用VSCode连接到EC2实例5.部署WebSocket服务6.配置域名和SSL&#xff08;可选&#xff09;7.监控和维护 1.创建AWS账户 如果你还没有AWS账户&#xff0c;你需要先在AWS官网注册一个。 2.选择EC2实例 登录到AWS管理控制台。搜…...

常见的集合

1、Collection 单列集合的根接口 遍历方法 Collection<String> c new ArrayList<>(); c.add("赵敏"); c.add("小昭"); c.add("素素"); c.add("灭绝"); System.out.println(c); //[赵敏, 小昭, 素素, 灭绝]//1、迭代器遍…...

Swift知识点---RxSwift学习

1. 什么是RxSwift RxSwift是Swift函数响应式编程的一个开源库&#xff0c;由Github的ReactiveX组织开发、维护 RxSwift的目的是&#xff1a;让数据/事件流 和 异步任务能够更方便的序列化处理&#xff0c;能够使用Swift进行响应式编程 RxSwift本质上还是观察者模式&#xff…...