当前位置: 首页 > 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;…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...

CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?

在现代前端开发中&#xff0c;Utility-First (功能优先) CSS 框架已经成为主流。其中&#xff0c;Tailwind CSS 无疑是市场的领导者和标杆。然而&#xff0c;一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...