排序算法及源代码

news2025/2/28 12:59:16

堆排序:

在学习堆之后我们知道了大堆和小堆,对于大堆而言第一个节点就是对大值,对于小堆而言,第一个值就是最小的值。如果我们把第一个值与最后一个值交换再对最后一个值前面的数据重新建堆,如此下去就可以实现建堆排序。

建堆的两种方法:

向上调整建堆:

 向上调整建堆的思路是从第一个开始先后添加数据,在每次到一个数据是如果比父节点大(小)就与父节点交换位置并继续向上调整。

算法复杂度:O(N*logN) 

 向下调整建堆:

 因为对于大(小)堆来说它的左右子树也都应该是大(小)堆,以此类推我们最小的数也应该是大(小)堆,于是我们就从最小的树开始建堆。

算法复杂度:O(N) 

插入排序:

直接插入排序是认为要插入数之前的所有数据已经排序好,用一个tmp临时变量存储要插入的值,如果要插入值的前一个数据比他大,那么就向后覆盖,接着继续往前比,直到遇到比要插入值小的数据,将要插入值插入在该数据的后一位。

希儿排序:

 

事实上就是插入排序的升级版,对插入排序进行调整使数组趋于有序,最后一次进行一次插入排序。 

选择排序:

选择排序是从数据的首端去进行选择,遍历一遍数组取选出最大值和最小值,选出后交换放在两端排序,继续去选择。注意的是如果最大值是第一个数据,后面交换时会出现数据被替代的情况,这种情
况下我们需要在交换后将最大值下标指向最小值下标。

 

 

 快速排序:

递归:

 

 

 

非递归 :

归并排序: 

递归:

 

 非递归:

计数排序 :

其思想就是利用一个数组,数组名表示需要排序的数组里的数据,其大小就是出现次数,最后从大到小存在一个数组里。

#include "SORT.h"

void swap(int* a, int* b)
{
	//printf("%d %d --", *a, *b);
	int tmp = *a;
	*a = *b;
	*b = tmp;
	//printf("%d %d\n", *a, *b);
}

/*******************************************************************************/
/*---------------------------------堆排序------------------------------------- */
/*******************************************************************************/
void heapSort_F(int* arr,int n)//向下调整建堆
{
	//升序建大堆
	int last_father = (n - 1) / 2;					//找到第一个父
	while (last_father != -1)
	{
		int father = last_father;
		int child = father * 2 + 1;
		while (child <= n)
		{
			if (child + 1 <= n && arr[child + 1] > arr[child])		//找到最大的孩子
			{
				++child;
			}
			if (arr[father] < arr[child])					//孩子比父亲大就交换
			{
				int tmp = arr[father];
				arr[father] = arr[child];
				arr[child] = tmp;
			}
			father = child;						//继续向下(大的往上走作为父)
			child = father * 2 + 1;
		}									//大堆好了
		--last_father;
	}
	while (n)
	{
									//交换首尾巴size--
		int tmp = arr[0];
		arr[0] = arr[n];
		arr[n] = tmp;
		--n;

		int father = 0;
		int child = father * 2 + 1;
		while (child <= n)				//向下找大的作为父
		{
			if (child + 1 <= n)
			{
				if (arr[child + 1] > arr[child])++child;
			}
			if (arr[father] < arr[child])
			{
				int tmp = arr[father];
				arr[father] = arr[child];
				arr[child] = tmp;
			}
			father = child;
			child = father * 2 + 1;
		}
	}
}


void heapSort_S(int* arr, int n)//向上调整建堆
{
	//降序建小堆
	for (int i = 1; i <= n; i++)			//从前往后插入,每插入一个判断上面的父是否需要向上改变
	{
		int child = n;
		while (child)
		{
			int father = (child - 1) / 2;
			if (arr[father] > arr[child])
			{
				int tmp = arr[child];
				arr[child] = arr[father];
				arr[father] = tmp;
			}
			child = father;
		}
	}
	while (n)
	{
		int tmp = arr[0];
		arr[0] = arr[n];
		arr[n] = tmp;
		
		--n;
		int father = 0;
		int child = father * 2 + 1;
		while (child <= n)
		{
			if (child + 1 <= n)
			{
				if (arr[child + 1] < arr[child])++child;
			}
			if (arr[father] > arr[child])
			{
				int tmp = arr[father];
				arr[father] = arr[child];
				arr[child] = tmp;
			}
			father = child;
			child = father * 2 + 1;
		}
	}
}
/*=======================================================================================*/
/*=======================================================================================*/


/*******************************************************************************/
/*--------------------------------插入排序------------------------------------ */
/*******************************************************************************/
void InsertSort(int* arr, int n)
{
	int end = 0;
	while (end != n - 1)
	{
		++end;
		int val = arr[end];
		int change = end;
		while (change != 0)
		{
			if (arr[change - 1] > val)
			{
				arr[change] = arr[change - 1];
				--change;
			}
			else break;
		}arr[change] = val;
	}
}
//void InsertSort(int* a, int n)
//{
//	//  [0, n-1]
//	for (int i = 0; i < n - 1; i++)
//	{
//		// [0, n-2]是最后一组
//		// [0,end]有序 end+1位置的值插入[0,end],保持有序
//		int end = i;
//		int tmp = a[end + 1];
//		while (end >= 0)
//		{
//			if (tmp < a[end])
//			{
//				a[end + 1] = a[end];
//				--end;
//			}
//			else
//			{
//				break;
//			}
//		}
//		a[end + 1] = tmp;
//	}
//}
//
/*=======================================================================================*/
/*=======================================================================================*/


/*******************************************************************************/
/*--------------------------------希儿排序------------------------------------ */
/*******************************************************************************/
void ShellSort(int* arr, int n)
{
	int gap = n;
	while(gap>1)
	{
		gap = gap / 3 + 1;
		//for (size_t j=0; j < gap; j++)
		//{
		//	for (size_t i = j; i < n-gap; i+=gap)   //一组一组
		for (size_t i = 0; i < n - gap; ++i)    //多组并着走
		{
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (tmp < arr[end])
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}arr[end + gap] = tmp;
		}
	//}
	}
}
/*=======================================================================================*/
/*=======================================================================================*/


/*******************************************************************************/
/*------------------------------  选择排序  ---------------------------------- */
/*******************************************************************************/
void SelectSort(int* arr, int n)
{
	int start = 0; int end = n - 1;
	while (start < end)
	{
		int mini = start;
		int maxi = end;
		for (int i = start; i <= end; i++)
		{
			if (arr[i] < arr[mini])mini = i;
			if (arr[i] > arr[maxi])maxi = i;
		}
		swap(&arr[start], &arr[mini]);
		if (start == maxi)
		{
			maxi = mini;
		}
		swap(&arr[end], &arr[maxi]);
		++start;
		--end;
	}
}
/*=======================================================================================*/
/*=======================================================================================*/


/*******************************************************************************/
/*--------------------------------快速排序------------------------------------ */
/*******************************************************************************/
int get_midi(int* arr, int left, int right)         //优化--三值取中
{
	int midi = (left + right) / 2;
	if (arr[midi] < arr[left])
	{
		if (arr[midi] > arr[right])return midi;
		else
		{
			if (arr[left] > arr[right])return left;
			else return right;
		}
	}
	else
	{
		if (arr[midi] < arr[right])return midi;
		else
		{
			if (arr[left] > arr[right])return left;
			else return right;
		}
	}
}
// 霍尔版
int partSort1(int* arr, int left, int right)
{
	if (right - left < 10)//小区间优化
	{
		InsertSort(&arr[left], right - left + 1);
	}
	int midi = get_midi(arr, left, right);
	int keyi = left;
	swap(&arr[midi], &arr[keyi]);
	int key = arr[left];
	int begin = left, end = right;
	while (begin < end)
	{
		//向右找小
		while (arr[end] >= key && begin < end)
		{
			--end;
		}
		//向左找大
		while (arr[begin] <= key && begin < end)
		{
			++begin;
		}
		swap(&arr[begin], &arr[end]);
	}
	swap(&arr[keyi], &arr[end]);
	return begin;
}
// 双指针
int partSort2(int* arr, int left, int right)
{
	int keyi = left;
	int key = arr[left];
	int prev = left;
	int cur = prev + 1;
	while (cur<=right)
	{
		if (arr[cur] < key && ++prev != cur)
			swap(&arr[cur], &arr[prev]);
		++cur;
	}
	swap(&arr[prev], &arr[keyi]);
	return prev;
}

void QuickSort(int* arr, int left, int right)
{
	if (left >= right)return;
	else
	{
		int begin = partSort2(arr, left, right);    //双指针
		//int begin = partSort1(arr, left, right);    //霍尔版
		QuickSort(arr, left, begin - 1);
		QuickSort(arr, begin + 1, right);
	}
	
}
/*=======================================================================================*/
/*=======================================================================================*/

/*******************************************************************************/
/*---------------------------快速排序(非递归)------------------------------- */
/*******************************************************************************/
void quickSortNonR(int* arr, int left, int right)
{
	ST st;
	STinit(&st);
	STpush(&st, left);
	STpush(&st, right);
	while (!STEmpty(&st))
	{
		int end = STtop(&st);
		STpop(&st);
		int begin = STtop(&st);
		STpop(&st);
		int mid = partSort1(arr, begin, end);
		if (mid - 1 > begin)
		{
			STpush(&st, begin);
			STpush(&st, mid - 1);
		}
		if (mid + 1 < end)
		{
			STpush(&st, mid + 1);
			STpush(&st, end);
		}
	}
}
/*=======================================================================================*/
/*=======================================================================================*/



/*******************************************************************************/
/*--------------------------------归并排序------------------------------------ */
/*******************************************************************************/
void _mergeSort(int* arr, int* tmp, int begin, int end)
{
	if (begin >= end)
		return;

	int mid = (begin + end) / 2;

	_mergeSort(arr, tmp, begin, mid);
	_mergeSort(arr, tmp, mid + 1, end);

	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;

	int i = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (arr[begin1] < arr[begin2])
		{
			tmp[i++] = arr[begin1++];
		}
		else
		{
			tmp[i++] = arr[begin2++];
		}
	}
	while (begin1 <= end1)
		tmp[i++] = arr[begin1++];
	while (begin2 <= end2)
		tmp[i++] = arr[begin2++];
	memcpy(arr + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}
void mergeSort(int* arr, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	_mergeSort(arr, tmp, 0, n-1);
	free(tmp);
}
/*=======================================================================================*/
/*=======================================================================================*/


/*******************************************************************************/
/*---------------------------归并排序(非递归)------------------------------- */
/*******************************************************************************/
void mergeSortNonR(int* arr, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n; i += gap * 2)
		{
			int j = i;
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
			if (begin2 >= n)
				break;
			if (end2 >= n)
				end2 = n - 1;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (arr[begin1] < arr[begin2])
				{
					tmp[j++] = arr[begin1++];
				}
				else
				{
					tmp[j++] = arr[begin2++];
				}
			}
			while (begin1 <= end1)
				tmp[j++] = arr[begin1++];
			while (begin2 <= end2)
				tmp[j++] = arr[begin2++];
			memcpy(arr + i, tmp + i, sizeof(int) * (end2 - i + 1));
		}
		gap *= 2;
	}
	free(tmp);
}
/*=======================================================================================*/
/*=======================================================================================*/


/*******************************************************************************/
/*--------------------------------计数排序------------------------------------ */
/*******************************************************************************/

void count_Sort(int* arr, int sz)
{
	int max = arr[0];
	int min = arr[0];
	for (int i = 0; i < sz; i++)
	{
		if (arr[i] > max)
			max = arr[i];
		if (arr[i] < min)
			min = arr[i];
	}
	int* tmp = (int*)calloc(max - min + 1, sizeof(int));
	for (int i = 0; i < sz; i++)
	{
		tmp[arr[i] - min]++;
	}
	int i = 0;
	for (int j = 0; j < max - min + 1; j++)
	{
		while (tmp[j]--)
		{
			arr[i++] = j + min;
		}
	}
}

/*=======================================================================================*/
/*=======================================================================================*/

 

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

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

相关文章

【Java】已解决java.util.concurrent.TimeoutException异常

文章目录 一、问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.util.concurrent.TimeoutException异常 一、问题背景 java.util.concurrent.TimeoutException是Java并发编程中常见的一个异常&#xff0c;它通常发生在使用Future或Future…

202483读书笔记|《把你写进诗歌里》——人生是一场不知何时散场的约会,爱慕向来短暂,失去才是唯一出路

202483读书笔记|《把你写进诗歌里》——人生是一场不知何时散场的约会&#xff0c;爱慕向来短暂&#xff0c;失去才是唯一出路 摘录 《把你写进诗歌里&#xff08;2020年度中国优秀诗歌&#xff09;》&#xff0c;作者上官文露。并不惊艳&#xff0c;中英文双语对照的一本诗集&…

OpenGL3.3_C++_Windows(13)

demo演示 demo演示 面剔除 当我们都以逆时针绘制三角形顶点&#xff0c;那么从三角形的背面看就是顺时针&#xff0c;面剔除正是根据这个原理&#xff0c;glEnable&#xff08;&#xff09;首先启用&#xff0c;glCullFace&#xff08;&#xff09;改变需要剔除的面类型&#…

【Java面试】二十一、JVM篇(中):垃圾回收相关

文章目录 1、类加载器1.1 什么是类加载器1.2 什么是双亲委派机制 2、类装载的执行过程&#xff08;类的生命周期&#xff09;3、对象什么时候可以被垃圾回收器处理4、JVM垃圾回收算法4.1 标记清除算法4.2 标记整理算法4.3 复制算法 5、分代收集算法5.1 MinorGC、Mixed GC、Full…

初阶 《数组》 1. 一维数组的创建和初始化

1. 一维数组的创建和初始化 1.1 数组的创建 数组是一组相同类型元素的集合 数组的创建方式&#xff1a; type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n 是一个常量表达式&#xff0c;用来指定数组的大小数组创建的实例&#xff1a; //代码1 int ar…

计算机图形学入门16:曲线

1.曲线 曲线&#xff08;Curves&#xff09;在图形学中应用非常广泛&#xff0c;比如&#xff1a;相机的拍摄路径、物体的移动路径、动画曲线、矢量字体等。如下图所示&#xff0c;是使用曲线到矢量字体的应用&#xff0c;通过移动一些控制点来改变字体。 2.贝塞尔曲线 2.1 贝…

qt事件和连接TCP协议

QT网络聊天室服务器实现 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget),server(new QTcpServer(this))//给服务器指针实例化一个空间 {ui->setupUi(this); }Widget::~Widget() {d…

Git进阶使用(图文详解)

文章目录 Git概述Git基础指令Git进阶使用一、Git分支1.主干分支2.其他分支2.1创建分支2.2查看分支1. 查看本地分支2. 查看远程分支3. 查看本地和远程分支4. 显示分支的详细信息5. 查看已合并和未合并的分支 2.3切换分支1. 切换到已有的本地分支2. 创建并切换到新分支3. 切换到远…

MyPostMan:按照项目管理接口,基于迭代生成接口文档、执行接口自动化联合测试

MyPostMan 是一款类似 PostMan 的接口请求软件&#xff0c;不同于 PostMan 的是&#xff0c;它按照 项目&#xff08;微服务&#xff09;、目录来管理我们的接口&#xff0c;基于迭代来管理我们的接口文档&#xff0c;按照迭代编写自动化测试用例&#xff0c;在不同环境中均可运…

ASP.NET MVC企业级程序设计(增删,页面水平排列,字符串拼接,非空,添加框内默认提示)

目录 题目&#xff1a; 实现过程 控制器代码 DAL BLL Index Deile 题目&#xff1a; 实现过程 控制器代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MvcApplication1.Models;namespac…

oracle中执行select ... for update需要什么权限?

oracle中执行select … for update需要什么权限&#xff1f; 问题 在oracle中&#xff0c;一个用户执行select … for update需要什么权限&#xff1f; 分析测试 用户1&#xff1a; test_0614 用户2&#xff1a;test 目标表&#xff1a;test.t_0614 执行语句&#xff1a;se…

机器学习课程复习

参考书目:《统计学习方法》 选择题 5道 3分/道 填空题 5道 3分/道 简答题 3道 计算题 1道 算法设计题 1道 隐马尔可夫不考计算题 很有可能考计算题的知识点:KNN、决策树、支持向量机、聚类算法 小概率会考计算题的知识点:线性回归(最小二乘法,代公式算参…

代码随想录——全排列(Leetcode LCR083)

题目链接 回溯 class Solution {List<List<Integer>> res new ArrayList<List<Integer>>();List<Integer> list new ArrayList<Integer>();boolean[] used;public List<List<Integer>> permute(int[] nums) {used new bo…

密码学及其应用——为什么选择接近的质数因子对RSA加密算法不安全?

RSA加密算法是一种广泛使用的非对称加密算法&#xff0c;它的安全性依赖于大整数分解的难度。具体来说&#xff0c;RSA算法生成的公钥包含一个大整数N&#xff0c;这是两个大质数p和q的乘积。然而&#xff0c;如果这两个质数p和q太接近&#xff0c;则可以相对容易地对N进行因式…

【Python机器学习实战】 | Lasso回归和弹性网回归详细分析研究

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

【STM32】矩阵计算器

【STM32】矩阵计算器 资料链接请在文章末尾获取~ 1.说明 使用元器件&#xff1a;stm32f103c8t6最小系统板x1&#xff0c;0.96寸OLED显示屏四角x1&#xff0c;4x4矩阵按键x1; 参考&#xff1a;正点原子有关4脚OLED驱动float型数据的驱动文件&#xff0c;CSDN有关矩阵横向扫描…

网络安全:入侵检测系统的原理与应用

文章目录 网络安全&#xff1a;入侵检测系统的原理与应用引言入侵检测系统简介IDS的工作原理IDS的重要性结语 网络安全&#xff1a;入侵检测系统的原理与应用 引言 在我们的网络安全系列文章中&#xff0c;我们已经涵盖了从SQL注入到端点保护的多个主题。本篇文章将探讨入侵检…

八大排序————C语言版实现

Hello&#xff0c;各位未来的高级程序员们&#xff0c;大家好&#xff0c;今天我就来为大家讲解一下有关排序的内容&#xff0c;我们常见的排序就是我们接下来要讲的这八个排序&#xff0c;我们平常所说的排序有十大排序&#xff0c;我们这里的八大排序是我们生活中最为常见的八…

【机器学习】:线性回归模型学习路线

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

探究布局模型:从LayoutLM到LayoutLMv2与LayoutXLM

LAYOUT LM 联合建模文档的layout信息和text信息&#xff0c; 预训练 文档理解模型。 模型架构 使用BERT作为backbone&#xff0c; 加入2-D绝对位置信息&#xff0c;图像信息 &#xff0c;分别捕获token在文档中的相对位置以及字体、文字方向、颜色等视觉信息。 2D位置嵌入 …