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

常见的几种排序算法

目录

一、插入排序

1、直接插入排序

1.1、排序方法

1.2、图解分析

1.3、代码实现

2、希尔排序

2.1、排序方法

2.2、图解分析

2.3、代码实现

二、选择排序

1、直接选择排序

1.1、排序方法

1.2、图解分析

1.3、代码实现

2、堆排序

2.1、排序方法

2.2、图解分析

2.3、代码实现

三、交换排序

1、冒泡排序

1.1、排序方法

1.2、图解分析

1.3、代码实现

2、快速排序

2.1、hoare排序

2.1.1、图解分析

2.1.2、代码实现

2.2、挖坑法

2.2.1、图解分析

2.2.2、代码实现

2.3、前后指针法

2.3.1、图解分析

2.3.2、代码实现

四、归并排序

1、排序方法

2、图解分析

3、代码实现


一、插入排序

        基本思想:把待排序的数据按其关键码值的大小追个插入到一个有序序列中,得到一个新的有序序列。

1、直接插入排序

1.1、排序方法

        当插入第i个元素时,数组的前i-1个元素已经有序,将第i个元素与前i-1个元素的关键码值进行比较,找到合适的位置插入,并将该位置之后的所有元素顺序后移即可。

1.2、图解分析

1.3、代码实现

// 直接插入排序
void InsertSort(int* a, int n)
{for (int i = 0; i < n; i++){int tmp = a[i];int end = i-1;while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;;}
}

2、希尔排序

2.1、排序方法

        希尔排序是对直接插入排序的优化。希尔排序的基本思想是:先选定一个合理的增量gap,把待排序文件中的数据分成gap个组,每一组中的相邻元素位置相差gap的距离,对每组元素各自进行直接插入排序。然后适当缩小gap,重复上述操作。直到gap等于1时,所有元素在同一组内最后一次直接插入排序。

2.2、图解分析

2.3、代码实现

// 希尔排序
void ShellSort(int* a, int n)
{int gap = n;while (gap > 1){bool change = false;gap = gap / 3 + 1;for (int i = 0; i < n - gap; i++){int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end-=gap;change = true; }else{break;}}a[end + gap] = tmp;;}if (change == false){break;}}
}

二、选择排序

        基本思想:每次从待排序元素中选出最大(或最小)的一个元素将其存放在已有序序列的后一个位置,重复操作直到所有元素存放结束得到一个有序的新序列。

1、直接选择排序

1.1、排序方法

        在元素集合arr[i]~arr[n-1]中选出关键码值最大(小)的元素,若该元素不是第一个(或最后一个),则将其与这组元素中的第一个(或最后一个)元素进行交换,对剩余未排序元素重复上述操作直到结束。

1.2、图解分析

1.3、代码实现

// 选择排序
void SelectSort(int* a, int n)
{int begin_i = 0;int end_i = n-1;while (begin_i < end_i){int max_i = end_i;int min_i = begin_i;for (int i = begin_i; i <= end_i; i++){if (a[i] < a[min_i]){Swap(&a[i], &a[min_i]);}if (a[i] > a[max_i]){Swap(&a[i], &a[max_i]);}}begin_i++;end_i--;}
}

2、堆排序

2.1、排序方法

        堆排序的操作对象是堆,排序会调整部分节点在堆中的相对位置,为了不破坏堆的性质,我们将堆顶节点与堆的最后一个节点交换,再将除最后一个节点之外的其他节点通过向下调整算法调整成为一个新的堆。重复操作直到只剩下一个节点为止。

2.2、图解分析

2.3、代码实现

//堆排序typedef struct Heap
{int* a;int size;int capacity;
}Heap;//向下调整算法
void AdjustDwon(int* a, int n, Heap* hp)
{for (int parent = (n - 2) / 2; parent >= 0; parent--){int child = parent * 2 + 1;while (child < n){bool change = false;if (child + 1 < n){child = hp->a[child] > hp->a[child + 1] ? child : child + 1;}if (hp->a[child] > hp->a[parent]){int tmp = hp->a[parent];hp->a[parent] = hp->a[child];hp->a[child] = tmp;change = true;parent = child;child = parent * 2 + 1;}if (change == false){break;}}}
}//初始化堆
void InitialHeap(Heap* hp,int n)
{if (!hp){return;}int* tmp = (int*)malloc(sizeof(int) * n);if (!tmp){perror("InitialHeap::malloc:");return;}hp->a = tmp;hp->size = 0;hp->capacity = n;
}//创建堆
void HeapBuild(Heap* hp, int* a, int n)
{assert(hp);for (int i = 0; i < n; i++){hp->a[i] = a[i];}AdjustDwon(a, n, hp);
}//排序
void Sort(Heap* hp, int* a, int n)
{int end = n - 1;while (end > 0){int tmp = hp->a[0];hp->a[0] = hp->a[end];hp->a[end] = tmp;a[end] = hp->a[end];end--;AdjustDwon(a, end, hp);}a[0] = hp->a[0];
}

三、交换排序

        基本思想:根据序列中两个元素的关键码值的大小来判断是否需要交换他们在序列中的位置,默认将关键码值较大的元素向序列的尾部移动,关键码值较小的元素向序列的首部移动。

1、冒泡排序

1.1、排序方法

        冒泡排序是将待排序元素的关键码值最大(小)的元素通过从前往后依次两两比较交换到最后面的位置。每操作一次可以确定一个元素在有序序列中的的位置。

1.2、图解分析

1.3、代码实现

// 冒泡排序
void BubbleSort(int* a, int n)
{for (int j = 1; j < n; j++){for (int i = 0; i < n - j; i++){if (a[i] > a[i + 1]){int tmp = a[i];a[i] = a[i + 1];a[i + 1] = tmp;}}}
}

2、快速排序

        基本思想:快速排序是任取待排序元素序列中的某元素的关键码值作为基准值,按照该基准值将待排序集合分割成左右两个子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,再对左右子序列重复该过程直到结束。

2.1、hoare排序

2.1.1、图解分析

        key选左边,从右边出发。保证了相遇位置的值比key位置的值小;

        key选右边,从左边出发。保证了相遇位置的值比key位置的值大;

        (注意:key指的是下标)

2.1.2、代码实现

// 快速排序hoare版本
int PartSort1(int* a, int left, int right)
{int key = left;while (left < right){while (left < right && a[right] >= a[key]){right--;}while (left<right && a[left]<=a[key]){left++;}int tmp = a[right];a[right] = a[left];a[left] = tmp;}int tmp = a[key];a[key] = a[left];a[left] = tmp;return left;
}

2.2、挖坑法

2.2.1、图解分析

     ( 注意: 这里的key是一个变量,不是下标)

2.2.2、代码实现

// 快速排序挖坑法
int PartSort2(int* a, int left, int right)
{int key = a[left];int hole = left;while (left < right){while (hole < right){if (a[right] < key){a[hole] = a[right];hole = right;break;}right--;}while (hole > left){if (a[left] > key){a[hole] = a[left];hole = left;break;}left++;}}a[hole] = key;return hole;
}

2.3、前后指针法

2.3.1、图解分析

        (这里的key同样是一个变量,不是下标)

2.3.2、代码实现

// 快速排序前后指针法
int PartSort3(int* a, int left, int right)
{int prev = left;int cur = prev + 1;int key = a[left];while (cur <= right){if (a[cur] < key){prev++;int tmp = a[prev];a[prev] = a[cur];a[cur] = tmp;}cur++;}a[left] = a[prev];a[prev] = key;return prev;
}

四、归并排序

1、排序方法

        归并排序是建立在归并操作上的一种排序算法。归并排序是将已有序的子序列合并,得到完全有序的序列;即先使每个字序列有序,再使子序列段间有序。归并排序的核心思想是先分解后合并。

2、图解分析

3、代码实现

// 归并排序递归实现void _MergeSort(int* a, int begin, int end, int* tmp)
{if (begin >= end){return;}int mid = (begin + end) / 2;_MergeSort(a, begin, mid, tmp);_MergeSort(a, mid + 1, end, tmp);int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;int i = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] <= a[begin2]){tmp[i++] = a[begin1++];}else{tmp[i++] = a[begin2++];}}while (begin1 <= end1){tmp[i++] = a[begin1++];}while (begin2 <= end2){tmp[i++] = a[begin2++];}memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("MergeSort-->malloc:");return;}_MergeSort(a, 0, n - 1, tmp);free(tmp);tmp = NULL;
}

相关文章:

常见的几种排序算法

目录 一、插入排序 1、直接插入排序 1.1、排序方法 1.2、图解分析 1.3、代码实现 2、希尔排序 2.1、排序方法 2.2、图解分析 2.3、代码实现 二、选择排序 1、直接选择排序 1.1、排序方法 1.2、图解分析 1.3、代码实现 2、堆排序 2.1、排序方法 2.2、图解分析 …...

动态贴纸、美颜SDK与AR:创造独特的互动体验

目前&#xff0c;动态贴纸、美颜SDK、增强现实&#xff08;AR&#xff09;等技术是比较热门的话题&#xff0c;它们所结合的新兴玩法更是收到大家推崇&#xff0c;正潜移默化的改变我们与数字世界互动的方式。 一、动态贴纸&#xff1a;个性化互动的开始 动态贴纸&#xff0c…...

〔021〕Stable Diffusion 之 提示词反推、自动补全、中文输入 篇

✨ 目录 &#x1f388; 反推提示词 / Tagger&#x1f388; 反推提示词 Tagger 使用&#x1f388; 英文提示词自动补全 / Booru tag&#x1f388; 英文提示词自动补全 Booru tag 使用&#x1f388; 中文提示词自动补全 / tagcomplete&#x1f388; 中文提示词自动补全 tagcomple…...

如何实现响应式布局

要实现响应式布局&#xff0c;您可以采用以下方法&#xff1a; 视口设置&#xff1a; 在HTML的<head>部分中使用meta标签设置视口&#xff1a; <meta name"viewport" content"widthdevice-width, initial-scale1.0">使用百分比&#xff1a; 使…...

HTML <tr> 标签

实例 一个简单的 HTML 表格,包含两行两列: <table border="1"><tr><th>Month</th><th>Savings</th></tr><tr><td>January</td><td>$100</td></tr> </table>定义和用法 &l…...

点云从入门到精通技术详解100篇-点云多尺度分类网络

目录 前言 研究现状与发展趋势 国内外研究现状 点云处理应用研究现状...

电脑怎么设置定时关机,2个简单的操作

电脑作为现代生活中不可或缺的工具&#xff0c;我们通常会在工作或娱乐过程中使用它。但有时候&#xff0c;我们可能需要在一段时间后自动关机&#xff0c;例如在下载完成后或在睡觉前。那么电脑怎么设置定时关机呢&#xff1f;为了满足这种需求&#xff0c;电脑提供了多种定时…...

Uboot指令与烧录

目录 1 NAND Flash&#xff1a; 1&#xff09;地址空间说明 2&#xff09;烧写u-boot 3&#xff09;烧写内核 4&#xff09;烧写文件系统 5&#xff09;设置启动参数 2 SPI Flash&#xff1a; 1&#xff09;地址空间说明 2&#xff09;烧写u-boot 3&#xff09;烧写内…...

Visual Studio中使用预编译头文件

预编译头文件&#xff08;Precompiled Header&#xff0c;PCH&#xff09;是一种C/C编译优化技术&#xff0c;用于提高大型项目的编译速度。PCH 文件包含了常用的头文件的预编译结果&#xff0c;它可以在编译其他源文件之前被加载到内存中&#xff0c;从而减少了重复的头文件解…...

C语言:选择+编程(每日一练Day15)

目录 选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;寻找奇数 思路一&#xff1a; 题二&#xff1a;寻找峰值 思路一&#xff1a; 本人实力有限可能对一些地方解…...

确定Mac\Linux系统的架构类型是 x86-64(amd64),还是 arm64 架构

我们在下载软件或镜像时会有很多版本&#xff0c;那需要根据我们的系统架构选择正确的软件或镜像版本。 要确定你的系统使用的是 x86-64&#xff08;amd64&#xff09; 还是 arm64 架构&#xff0c;可以使用以下方法之一&#xff1a; 使用 uname 命令&#xff1a; 打开终端&am…...

Python脚本

update_format.py 批量转视频格式&#xff0c;超级慢&#xff0c;没什么卵用 import os import asyncio import subprocess import concurrent.futures import tracemalloctracemalloc.start()# 创建日志文件 log_file open(conversion_log.txt, w)async def convert_mkv_t…...

Kotlin的遍历方法

for循环 在下面代码中1…10表示的是1到10&#xff0c;两边都是闭包&#xff0c;输出12345678910 for (i in 1..10) println(i)加上花括号也支持 for (i: Int in 1..10) {println(i)}另外&#xff0c;当对整数进行for循环时&#xff0c;Kotlin还提供了一个step函数来定义迭代的…...

AskIt: Unified Programming Interface for Programming with Large Language Models

本文是LLM系列文章&#xff0c;针对《AskIt: Unified Programming Interface for Programming with Large Language Models》的翻译。 AskIt&#xff1a;用于大型语言模型编程的统一编程接口 摘要1 引言2 动机例子3 设计与实现4 实验评估5 相关工作6 结论 摘要 在不断发展的软…...

【wireshark抓取数据包-PGSQL协议】

测试查看PGSQL协议的网络流量数据明细 &#xff11;&#xff09;捕获过滤的条件设置&#xff0c;tcp.port5432(数据库的端口&#xff09; &#xff12;&#xff09;上面是wireshark的主窗口&#xff0c;分三大主块&#xff1a;Packlist List&#xff08;数据包列表&#xff09…...

【idea学习】

1.debug: 文章详解 2.导入SpringBoot项目 文章详情...

ZooKeeper数据模型/znode节点深入

1、Znode的数据模型 1.1 Znode是什么&#xff1f; Znode维护了一个stat结构&#xff0c;这个stat包含数据变化的版本号、访问控制列表变化、还有时间戳。版本号和时间戳一起&#xff0c;可让Zookeeper验证缓存和协调更新。每次znode的数据发生了变化&#xff0c;版本号就增加。…...

容器编排工具的比较:Kubernetes、Docker Swarm、Nomad

随着容器化技术的普及&#xff0c;容器编排工具成为了现代应用部署和管理的重要组成部分。容器编排工具能够自动化容器的部署、扩展和管理&#xff0c;从而提高应用的可靠性和可伸缩性。在众多的容器编排工具中&#xff0c;Kubernetes、Docker Swarm和Nomad是三个备受关注的主要…...

nginx--技术文档--架构体系--底层核心-原理

Nginx的架构体系可以概括为“一个核心、两个模型。” “一个核心”指Nginx的核心功能&#xff0c;即HTTP请求处理。Nginx作为一个高性能的Web服务器&#xff0c;其核心功能是处理HTTP请求&#xff0c;包括接收请求、解析请求、处理请求和返回响应等。 “两个模型”指Nginx的多…...

Java23种设计模式之【单例模式】

目录 一.单例模式的起源&#xff0c;和应用场景 1.单例模式的前世今生&#xff01; 2.什么是单例模式&#xff1f; 2.1使用单例模式的注意事项 2.2如何理解单例模式&#xff1f; 2.3单例模式的优势以及不足&#xff01; 2.4使用场景 二.实现 1.实现思路 1.1创建一个 S…...

交互弹窗设计避坑指南:Toast、Dialog、Actionbar和Snackbar的常见错误与优化建议

交互弹窗设计避坑指南&#xff1a;Toast、Dialog、Actionbar和Snackbar的常见错误与优化建议 在移动应用和网页设计中&#xff0c;交互弹窗是用户界面中不可或缺的元素。它们像数字世界中的交通信号灯&#xff0c;引导用户完成各种操作流程。然而&#xff0c;设计不当的弹窗不仅…...

OpenClaw+千问3.5-9B成本优化:夜间定时任务实战

OpenClaw千问3.5-9B成本优化&#xff1a;夜间定时任务实战 1. 为什么选择夜间执行AI自动化任务&#xff1f; 去年冬天的一个深夜&#xff0c;我被服务器告警短信吵醒。查看日志发现是日间运行的AI数据处理任务消耗了过多Token&#xff0c;触发了预算警报。这次意外让我开始思…...

pandas高效筛选技巧:如何精准匹配与排除DataFrame中的特定字符串列

1. 字符串筛选的常见场景与痛点 做数据分析的朋友们应该都遇到过这样的需求&#xff1a;从海量数据中快速找出包含特定关键词的记录。比如电商平台要筛选出所有包含"促销"字样的商品标题&#xff0c;或者客服系统需要过滤掉所有包含"投诉"关键词的工单。这…...

免费域名会不会对网站SEO造成影响_免费域名对网站性能和访问速度有影响吗

免费域名会不会对网站SEO造成影响 在互联网时代&#xff0c;网站的建设和推广是每个企业和个人都必须面对的挑战。其中&#xff0c;域名作为网站的身份和地址&#xff0c;对于网站的SEO&#xff08;搜索引擎优化&#xff09;有着重要影响。而免费域名的出现&#xff0c;给许多…...

VS2019+CMake实战:Super4PCS点云配准从源码编译到运行全流程指南

VS2019CMake实战&#xff1a;Super4PCS点云配准从源码编译到运行全流程指南 在三维视觉和机器人领域&#xff0c;点云配准一直是核心难题之一。Super4PCS算法作为4PCS的改进版本&#xff0c;以其在低重叠率点云上的优异表现&#xff0c;成为工业检测和SLAM系统中的热门选择。本…...

号令天下:守财数字能量号组413与313能守财吗

在数字能量学的体系中&#xff0c;延年磁场是主导守财的核心能量&#xff0c;天医磁场主打招财纳福&#xff0c;生气磁场侧重拓展人脉&#xff0c;二者并不具备直接的守财属性。像 413、313 这类组合&#xff0c;核心作用集中在招财聚财方面&#xff0c;守财能力相对薄弱&#…...

Threejs 使用Line2实现自定义线条宽度的实战指南

1. 为什么Three.js默认的lineWidth设置无效&#xff1f; 很多Three.js开发者第一次尝试修改线条宽度时&#xff0c;都会遇到一个令人困惑的问题&#xff1a;明明设置了lineWidth属性&#xff0c;但渲染出来的线条始终是1像素宽。这个问题其实源于WebGL的底层限制。WebGL基于Ope…...

I2C设备扫描器:嵌入式系统总线拓扑发现与地址诊断工具

1. I2C设备扫描器&#xff1a;嵌入式系统中总线拓扑发现的核心工具IC&#xff08;Inter-Integrated Circuit&#xff09;总线因其仅需两根信号线&#xff08;SCL时钟线与SDA数据线&#xff09;、支持多主多从架构、内置仲裁与应答机制等特性&#xff0c;成为嵌入式系统中传感器…...

W5500 TCP客户端实战 | 02 - 从寄存器配置到数据收发的完整流程解析

1. W5500网络寄存器配置详解 第一次接触W5500芯片时&#xff0c;我被它密密麻麻的寄存器地址搞得头晕眼花。后来发现只要抓住几个核心寄存器&#xff0c;配置起来就像填快递单一样简单。先说说最关键的四个本地网络寄存器&#xff0c;它们相当于设备的"身份证"&#…...

2007 Text 3

2007 Text 3...