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

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

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

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

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...