常见的几种排序算法

news2024/12/28 22:52:22

目录

一、插入排序

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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt/C++音视频开发49-推流到各种流媒体服务程序

一、前言 最近将推流程序完善了很多功能&#xff0c;尤其是增加了对多种流媒体服务程序的支持&#xff0c;目前支持mediamtx、LiveQing、EasyDarwin、nginx-rtmp、ZLMediaKit、srs、ABLMediaServer等&#xff0c;其中经过大量的对比测试&#xff0c;个人比较建议使用mediamtx和…

QT DAY6

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);socket new QTcpSocket(this);//如果连接服务器成功&#xff0c;该客户端就会发射一个connected的信号。//我们…

【TypeScript学习】—基本类型(二)

【TypeScript学习】—基本类型&#xff08;二&#xff09; 一、TypeScript基本类型 //也可以直接用字面量进行类型声明let a:10; a10;//也可以使用 |来连接多个类型&#xff08;联合类型&#xff09;let b:"male"|"female"; b"male"; b"fe…

【Java】Java新特性--Records记录类型

Java 14引入了一个新的语言特性&#xff0c;即Records。Records是一种新的数据类&#xff0c;旨在简化Java中的数据类创建过程。它们提供了一种简洁的方式来创建具有默认的getter、setter、equals、hashCode和toString方法的不可变数据类。 以下是Records的基本语法&#xff1…

一文讲透:erp系统是什么?

erp系统是什么&#xff1f;这个看似简单的问题还真不好解答。因为现在99%的人都把ERP“系统”和ERP“软件”混淆了&#xff01; ERP原本主要是专注于制造业的信息化问题&#xff0c;我把它叫真正的ERP“系统”。 但现在基本上只要是一个软件系统都可以叫ERP系统&#xff0c;什…

【动态规划】面试题 08.01. 三步问题

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 文章目录 0. 题目解析1. 算法原理1.1 状态表示1.2 状态转移方程1.3初始化1.4 填表顺序1.5 返回值 2.算法代码 &#x1f427; 本篇是整个动态规划的…

9.2 消息对话框 画板 定时器

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//设置定时器timernew QTimer(this);timeidthis->startTimer(1000);connect(timer,&QTimer::timeout,this,&Widget::timeout_slot);speechernew QTextToSpeech(this);//边框this-&…

天眼情报分析——编程赛道——研究对象001续

前言&#xff1a; 此次情报分析依旧会分为几大块 一、ACWING 算法基础课 1.高精度加法和减法听都没听过 1.什么是高精度加减法&#xff1f; "高精度加法"和"高精度减法"是一类编程题目&#xff0c;通常出现在算法竞赛和在线编程平台上&#xff0c;比如…

金蝶云星空和金蝶云星空单据接口对接

金蝶云星空和金蝶云星空单据接口对接 接入系统&#xff1a;金蝶云星空 金蝶K/3Cloud&#xff08;金蝶云星空&#xff09;是移动互联网时代的新型ERP&#xff0c;是基于WEB2.0与云技术的新时代企业管理服务平台。金蝶K/3Cloud围绕着“生态、人人、体验”&#xff0c;旨在帮助企业…

【科研论文配图绘制】task8 总结与回顾

task8 总结与回顾&#xff0c;这次组队学习大致掌握了常见python绘图工具包的使用&#xff0c;整体上和matlab的语法类似&#xff0c;也是用画布形式控制元素的绘制。印象深刻的是seaborn的使用&#xff0c;在之前做波士顿房价预测时候先接触了seaborn绘制的散点图、直方图和核…

手写Ribbon基本原理

本文已收录于专栏 《中间件合集》 目录 概念说明什么是RibbonRibbon和Nginx负载均衡的区别 工作流程代码实现RibbonSDK发送请求端引入RibbonSDK和Nacos的依赖配置文件中填写负载均衡策略调用代码 接收请求端执行效果发送请求端接收请求端 总结提升 概念说明 什么是Ribbon Ribb…

揭秘企业标准化作业:提升效率、降低成本、保障质量!为什么需要推行?

企业标准化作业是现今生产车间中出现频率非常高的一个词&#xff0c;那么什么是企业标准化作业&#xff1f;企业为什么推行标准化作业&#xff1f;标准化作业的实施有哪些好处&#xff1f;实施过程又有哪些难点呢&#xff1f;今天就来说一说&#xff01; 企业标准化作业是对生产…

智能制造效率与创新:RFID智能设备的引领作用

在现代制造业中&#xff0c;如何提升生产效率、降低成本、实现创新已经成为制造企业持续追求的目标。随着科技的不断进步&#xff0c;智能制造RFID智能设备正逐渐成为实现这些目标的得力工具。本文将探讨智能制造RFID智能设备在提升制造效率和创新方面的引领作用。 实时生产监控…

如何使用ArcGIS去除卫星影像上的云

虽然目前发布的地图都是对云量进行过筛选&#xff08;一般低于20%&#xff09;&#xff0c;但是还是有可能会遇到有云的情况&#xff08;特别是下载历史影像的时候&#xff09;&#xff0c;那么这些云应该怎么去除呢&#xff0c;我们可以尝试使用ArcGIS进行处理。 识别像素 将…

通过使用过硫酸铵溶液轻松预处理铜催化剂基底具有独特底部轮廓的剥离光刻胶的开发

引言 石墨烯是sp2杂化碳原子的二维蜂窝晶格&#xff0c;自首次成功分离和表征单层石墨烯以来就引起了广泛关注。载流子迁移率、稳健的机械公差和高光学透明度为未来的超大规模器件的应用提供了巨大的利用机会。因此&#xff0c;英思特提出了化学剥离、外延生长、热解和化学气相…

FreeRTOS中断与任务之间同步(Error:..\..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c,422 )

前言&#xff1a; FreeRTOS中&#xff0c;中断需要注意几点&#xff1a; 何时使用中断&#xff1b;中断服务函数&#xff08;ISR&#xff09;要处理的数据量有多大&#xff0c;通常我们希望中断的切换越快越好&#xff0c;也就是说&#xff0c;ISR尽量采用耗时较少的处理方式…

2000-2022年上市公司融资约束SA指数(含原始数据+计算方法+计算结果)

2000-2022年上市企业的融资约束指数&#xff08;含原始数据计算方法计算结果&#xff09; 1、时间&#xff1a;2000-2022年 2、范围&#xff1a;沪深A股上市公司 3、指标&#xff1a; 证券代码、证券简称、统计截止日期、是否发生ST或*ST或PT、是否发生暂停上市、行业代码、…

【Java 基础篇】Java多态:让你的代码更灵活而强大

多态是面向对象编程中的一个重要概念&#xff0c;它允许我们在不同的对象上调用相同的方法&#xff0c;但根据对象的不同&#xff0c;可以产生不同的行为。在 Java 中&#xff0c;多态性是一个强大的特性&#xff0c;它有助于代码的可扩展性和可维护性。本篇博客将深入探讨 Jav…

javaee spring aop实现事务 项目结构

spring配置文件 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:context"http://www.springframewo…

搭建hadoop集群的常见问题及解决办法

问题一: namenode -format重复初始化 出现问题的原因是重复初始化时会重新生成集群ID&#xff0c;而dn还是原先的集群ID&#xff0c;两者不匹配时无法启动相应的dn进程。 怎么查找问题原因&#xff1a;在logs目录下找到对应节点的.log文件&#xff0c;使用tail -200 文件名来查…