排序算法及源代码

堆排序:

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

建堆的两种方法:

向上调整建堆:

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

算法复杂度: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;
		}
	}
}

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

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Kotlin 中的闭包函数

闭包函数是现代编程语言中一个重要的概念&#xff0c;Kotlin 作为一种现代的 JVM 语言&#xff0c;自然也支持闭包函数。本文将详细介绍闭包函数的概念、在Kotlin 中的使用方法&#xff0c;以及一些常见的应用场景。 什么是闭包函数&#xff1f; 闭包函数&#xff0c;也称为闭…

MySQL版本发布模型

MySQL 8.0 之后使用了新的版本控制和发布模型&#xff0c;分为两个主线&#xff1a;长期支持版&#xff08;LTS&#xff09;以及创新版。这两种版本都包含了缺陷修复和安全修复&#xff0c;都可以用于生产环境。 下图是 MySQL 的版本发布计划&#xff1a; 长期支持版 MySQL…

百元内平价蓝牙耳机推荐,四款高热度平价耳机推荐!

在追求高品质音乐体验的同时&#xff0c;我们也不得不考虑预算的限制&#xff0c;不过市面上有不少百元内平价蓝牙耳机&#xff0c;它们在保证音质和舒适度的同时&#xff0c;也兼顾了价格的亲民性&#xff0c;身蓝牙耳机测评的达人&#xff0c;经手过不少的百元蓝牙耳机&#…

考研数学强化,880+660正确打开方式

1800题基础做完了&#xff1f;做的怎么样&#xff01; 之所以问你做的怎么样&#xff0c;是因为1800题做的好坏&#xff0c;直接决定了你要不要开始做880题和660题。 有的同学1800题做的很好&#xff0c;做完1800题之后开始做880660没毛病 但是有的同学就是纯纯的为了做题而…

1980python个性化电影推荐管理系统mysql数据库Django结构layUI布局elasticsearch存储计算机软件工程网页

一、源码特点 python Django个性化电影推荐管理系统是一套完善的web设计系统mysql数据库 利用elasticsearch存储浏览数据 &#xff0c;对理解python编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 开发环境pycharm…

3dmax怎么渲染又快又清晰?

在3ds Max中&#xff0c;追求快速且清晰的渲染效果是每个设计师的目标。云渲染技术的出现&#xff0c;为这一目标提供了强大的支持。通过云渲染&#xff0c;设计师能够利用远程服务器的强大计算能力&#xff0c;实现快速渲染&#xff0c;同时保持图像的高清晰度。 一、3dmax怎么…

Jackson的使用

一引入依赖 <!--Jackson是spring-boot-starter-json的一个依赖&#xff08;spring-boot-starter-web中包含spring-boot-starter-json&#xff09;。也就是说&#xff0c;当项目中引入spring-boot-starter-web后会自动引入spring-boot-starter-json --> <dependency&g…

Flutter 项目设置 Flutter 版本

即便使用了 fvm 设置了版本&#xff0c;AdroidStudio Setting 中如果不修改路径&#xff0c;Editor 依然会编译错误。目前还没看懂如何通过命令、文件来记录AdroidStudio Setting中的设置。 fvm list 来查看 flutter 路径&#xff1a;

无问芯穹Qllm-Eval:制作多模型、多参数、多维度的量化方案

前言 近年来&#xff0c;大语言模型&#xff08;Large Models, LLMs&#xff09;受到学术界和工业界的广泛关注&#xff0c;得益于其在各种语言生成任务上的出色表现&#xff0c;大语言模型推动了各种人工智能应用&#xff08;例如ChatGPT、Copilot等&#xff09;的发展。然而…

【Java面试】二十二、JVM篇(下):JVM参数调优与排查

文章目录 1、JVM的参数在哪里设置2、常见的JVM调优参数有哪些3、常见的JVM调优工具有哪些4、Java内存泄漏的排查思路5、CPU飙高的排查思路 1、JVM的参数在哪里设置 war包部署&#xff0c;在tomcat中设置&#xff0c;修改TOMCAT_HOME/bin/catalina.sh 文件 jar包启动&#xff0…

模型算法—线性回归

线性回归是统计学中最常见的一种回归分析方法&#xff0c;用于建立自变量&#xff08;解释变量&#xff09;和因变量&#xff08;响应变量&#xff09;之间的线性关系。线性回归模型可以用来预测一个或多个自变量对应的因变量的值。 线性回归的基本形式如下&#xff1a; &…

指标管理与精益生产:制造业的双翼齐飞

在竞争激烈的制造业环境中&#xff0c;企业要想保持持续的竞争优势&#xff0c;不仅需要拥有高效的生产流程&#xff0c;更需要有科学的管理方法。指标管理系统和精益生产正是这其中的两大关键要素。本文将探讨制造业缺乏指标管理系统的弊端&#xff0c;以及指标管理和精益生产…

美业人专用宝藏系统、Java收银系统源码分享-美业SAAS系统的应用价值分析

美业SAAS系统&#xff08;Software as a Service&#xff09;在美容、美发、美甲等行业中具有重要的应用价值。这种系统为美业提供了一种数字化解决方案&#xff0c;帮助企业更高效地管理业务和客户关系。 以下是博弈美业SAAS系统的应用价值分析&#xff1a; 1.经营管理&#…

文件加密软件排行榜|常用三款文件加密软件推荐

Top 1: 安秉网盾文件加密软件 加密模式多样&#xff1a;采用多种加密模式&#xff0c;对企业重要的文档、图纸进行全方位360度保护。可根据企业不同工作场景设置不同的加密模式。 全透明加密&#xff1a;通过全透明加密模式&#xff0c;对企业重要的图纸文件类型进行全盘透明…

Python 基础:文件

目录 一、从文件中读取数据1.1 读取整个文件1.2 逐行读取 二、写入文件2.1 写入空文件2.2 写入多行2.3 附加到文件 遇到看不明白的地方&#xff0c;欢迎在评论中留言呐&#xff0c;一起讨论&#xff0c;一起进步&#xff01; 本文参考&#xff1a;《Python编程&#xff1a;从入…

从穷举法到插板法:Python解决求和为12的正整数组合20240619

从穷举法到插板法&#xff1a;Python解决求和为12的正整数数学问题 在这篇博客中&#xff0c;我们将使用Python来解决一个有趣的小学数学问题&#xff1a;求出所有正整数组合&#xff0c;使得这些数的和为12。我们将演示如何找到这些组合&#xff0c;并计算每个组合的排列数&a…

【UIDynamic-动力学-UICollisionBehavior-碰撞行为-4个代理方法 Objective-C语言】

一、接下来,我们来说这个碰撞的代理方法, 1.我们把之前的代码再来复制一份儿,改个名字:07-碰撞行为-代理, 首先,在这个Collision里边,它有一个代理,我们找到这个行为,UICollisionBehavior,点进来看一下, 点进来, 在最下边,有一个delegate, 这个delegate,叫做UIC…

数据结构之探索“队列”的奥秘

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 队列有关概念 队列的使用 队列模拟实现 循环队列的模拟实现 622. 设计循环队列 双端队…

仓库管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;公告管理&#xff0c;物资管理&#xff0c;基础数据管理&#xff0c;用户管理 用户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公告管理&#xff0c;物…