八大排序

news2024/9/25 9:29:01

目录

选择排序-直接插入排序

插入排序-希尔排序

选择排序-简单选择排序

选择排序-堆排序

交换排序-冒泡排序

交换排序-快速排序

归并排序

基数排序

选择排序-直接插入排序

基本思想:

如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

具体代码实现:

void InsertSort(int* const arr, const int len)
{
	assert(arr);
	for (int i = 0; i < len; i++)//遍历每个元素
	{
		for (int j = i; j > 0; j--)//与前面的元素相比较
		{
			if (arr[j] < arr[j - 1])
				swap(arr + j, arr + j - 1);
			else                    //已经有序
				break;
		}
	}
}

复杂度分析

时间复杂度O(N^2),空间复杂度O(1)

插入排序是一种稳定的排序算法,当元素集合越接近有序,直接插入排序算法的时间效率越高。

插入排序-希尔排序

基本思想:

 对待排序数组中的元素进行分组,从第一个元素开始,按照数组下标中间隔为gap大小的元素分为一组,对每一组进行排序,重新选择gap的大小使得原始数据更加有序,当gap=1的时候就是插入排序。

代码实现:

void ShellSort(int* const arr, const int len)
{
	int gap = len;
	while (gap > 1)
	{
		gap = gap / 3 + 1;//调整gap的大小,gap=1的时候,为插入排序
		for (int i = gap; i < len; i++)//总共只需要循环len-gap次
		{
			for (int j = i; j >= gap; j-=gap)//插入排序
			{
				if (arr[j] < arr[j - gap])
				{
					swap(arr + j, arr + j - gap);
				}
				else
					break;
			}
		}
	}
}

这里的分组比较不是分开进行的(第一组比完第二组在比),而是多组同时进行比较,从第gap个元素开始,逐渐往前比较,每次和自己和自己gap距离的元素比较

复杂度分析:O(N^1.3 - N^2)

稳定性:不稳定

选择排序-简单选择排序

基本思想:

 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序数据元素排完.

代码实现:

void SelectSort(int*a,int n)
{
	int left=0;
	while(left<n)
	{
			int min=left; 
			for(int i=left;i<n;i++)//找最小值  
			{
				if(a[min]>a[i])
				{
				   min=i;
				}
			}
			Swap(&a[left],&a[min]);//交换数据   然后找次小,交换 
			left++;	
	}      
} 

 时间复杂度O(n^2),空间复杂度O(1);不稳定

选择排序-堆排序

基本思想:

堆排序是基于数据结构堆设计的一种排序算法,通过堆来选择数据,向上(向下)调整,得到小数(大数),然后再与堆底数据进行交换,即可排序,需要注意的是排升序建大堆,排降序建小堆

代码实现:

代码实现:

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
void AdjustDwon(int* a, int n, int root)
{
	int parent = root;
	int child = parent * 2 + 1;//找到孩子
	while (child < n)
	{
		if (child + 1 < n && a[child + 1] > a[child])//考虑右孩子越界和判断那个孩子大
		{
			++child;
		}
 
		if (a[child] > a[parent])//判断孩子和父亲谁大,孩子大,向上交换
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
void HeapSort(int* a, int n)
{
	// 升序  建大堆
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDwon(a, n, i);
	}
 
	int end = n - 1;//向下调整,交换
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDwon(a, end, 0);
		--end;
	}
}

时间复杂度O(n*logn),空间复杂度O(1); 不稳定 

交换排序-冒泡排序

基本思想:

代码实现:

//冒泡排序 
void Bubblesort(int *a,int n)
{
	for(int i=0;i<n;i++)//控制交换次数 
	{
		for(int j=0;j<n-i-1;j++)//向后冒泡 ,控制边界 
		{
			if(a[j]>a[j+1])//如果前一个值大于后一个值,交换. 
			{
				swap(&a[j],&a[j+1]);
			}		
		}
	}
} 

 时间复杂度O(n^2),空间复杂度O(1)  稳定

交换排序-快速排序

基本思想:

代码实现:

int PartSort1(int* a, int left, int right)
{
	int keyi = left;
	while (left < right)
	{
		// 找小
		while (left < right && a[right] >= a[keyi])
			--right;
 
		// 找大
		while (left < right && a[left] <= a[keyi])
			++left;
 
		swap(&a[left], &a[right]);//交换左右值
	}
	swap(&a[keyi], &a[left]);//最后交换key与left
 
	return left;//返回当前节点,[0,left-1],[left+1,right]递归排序
}

快排优化:

若初始序列按关键码有序或基本有序时,快排序反而蜕化为冒泡排序。为改进之,通常以“三者取中法”来选取基准记录,即将排序区间的两个端点与中点三个记录关键码居中的调整为支点记录,本质在于防止最坏的情况发生(1,已经有序2,数据全部相等)

为了避免这种情况,选取头尾和中间元素,比较大小,找大小处于中间的元素为key值,实现对快排的优化,时间复杂度仍为O(nlog^n),每次调用排序的时候把key置一下.

//快排三数优化
int  GetMid(int* a, int left, int right) 
{
	int mid = (left + right) >> 1;
		// left  mid  right
		if (a[left] < a[mid])
		{
			if (a[mid] < a[right])
			{
				return mid;
			}
			else if (a[left] > a[right])
			{
				return left;
			}
			else
			{
				return right;
			} 
		}
		else // a[left] > a[mid]
		{
			if (a[mid] > a[right])
			{
				return mid;
			}
			else if (a[left] < a[right])
			{
				return left;
			}
			else
			{
				return right;
			}
		}
}

时间复杂度:O(N*logN)  空间复杂度:O(N*logN)  不稳定
 

归并排序

基本思想:

 代码实现:

//归并排序 
void merge(int*a,int*arr,int left,int mid,int right)
{
	//标记左半区第一个未排序的元素
	int l_pos=left; 
	//标记右半区第一个未排序的元素
	int r_pos=mid+1;
	//临时数组下标的元素 
	int pos=left;
	//合并
	while(l_pos<=mid&&r_pos<=right)
	{
		if(a[l_pos]<a[r_pos])
		 arr[pos++]=a[l_pos++];
		 else
		 arr[pos++]=a[r_pos++];
	} 
	//合并左半区剩余的元素
	while(l_pos<=mid)
	{
		arr[pos++]=a[l_pos++];
	}
	//合并右半区剩余的元素
	while(r_pos<=right)
	{
		arr[pos++]=a[r_pos++];
	}
	//把临时数组合并后的元素复制到a中 
	while(left<=right)
	{
		a[left]=arr[left];
		left++;
	} 
}

 时间复杂度:O(N*logN)  空间复杂度:O(N)  稳定性:稳定

基数排序

基本思想:

 

代码实现:

void CountSort(int* a, int n)
{
	int max = a[0], min = a[0];
	for (int i = 0; i < n; ++i)
	{
		if (a[i] > max)
			max = a[i];
 
		if (a[i] < min)
			min = a[i];
	}
 
	int range = max - min + 1;
	int* count = malloc(sizeof(int)*range);
	memset(count, 0, sizeof(int)*range);
	for (int i = 0; i < n; ++i)//计数 
	{
		count[a[i] - min]++;
	}
 
	int i = 0;
	for (int j = 0; j < range; ++j)//排序 
	{
		while (count[j]--)
		{
			a[i++] = j + min;
		}
	}
 
	free(count);
}

时间复杂度:O(MAX(N,范围))  空间复杂度:O(范围)  稳定性:稳定

排序算法复杂度及稳定性分析

 

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

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

相关文章

如何高效地阅读 Python 代码?

原文首发于&#xff1a;如何高效地阅读 Python 代码&#xff1f; | 今是昨非 | 技术.生活.阅读.思考 副标题&#xff1a;一个重要但很少被讨论的技能 从网上看到这篇英文文章&#xff0c;感觉还不错&#xff0c;翻译了一下。Claude2 也有参与翻译&#x1f61d; AI摘要 这篇文…

Linux基础与拓展

文章目录 虚拟机网络连接方式VIMvi和vim常用的三种模式各种模式的相互切换快捷键 用户管理权限 基本介绍&#xff1a;添加用户指定/修改密码删除用户切换用户用户组 路径命令学习mkdir命令介绍语法注意 touch 创建文件介绍语法 cat 查看文件内容介绍语法 more 查看文件内容介绍…

vue3报错

这是因为eslint对代码的要求严格导致的&#xff0c;可以在package.json里面删掉"eslint:recommended"&#xff0c;然后重启就可以正常运行了

软件编程专业:探索计算机世界的奥秘

软件编程专业&#xff1a;探索计算机世界的奥秘 随着科技的飞速发展&#xff0c;计算机已经渗透到我们生活的方方面面。我们每天都在使用各种应用程序&#xff0c;比如社交媒体、游戏和电子邮件等&#xff0c;而这些应用程序背后的魔法都是由软件编程专业的人创造的。那么&…

Android 面试重点之Framework (Handler篇)

近期在网上看到不少Android 开发分享的面试经验&#xff0c;我发现基本每个面经中多多少少都有Framework 底层原理的影子。它也是Android 开发中最重要的一个部分&#xff0c;面试官一般会通过 Framework底层中的一些逻辑原理由浅入深进行提问&#xff0c;来评估应聘者的真实水…

idea - 刷新 Git 分支数据 / 命令刷新 Git 分支数据

一、idea - 刷新 Git 分支数据 idea 找到 fetch 选项&#xff0c;重新获取分支数据 二、命令刷新 Git 分支数据 git fetch参考链接 1. 远程Gitlab新建的分支在IDEA里不显示

Python-OpenCV中的图像处理-边缘检测

Python-OpenCV中的图像处理-边缘检测 边缘检测Canny算子 边缘检测Canny算子 Canny 边缘检测是一种非常流行的边缘检测算法&#xff0c;是 John F.Canny 在 1986 年提出的。它是一个有很多步构成的算法&#xff1a;噪声去除、计算图像梯度、非极大值抑制、滞后阀值等。 Canny(i…

kubernetes中最小组件——Pod

目录 一、Pod简介 二、Pod的使用方式 三、Pause——Pod中底层基础容器 四、为什么kubernetes这样设计Pod 五、Pod的分类 1.自主式Pod 2.控制器管理的Pod 3.静态Pod 六、Pod容器的分类 1. 基础容器&#xff08;infrastructure container&#xff09; 2. 初始化容器&am…

软件测试-------Web(性能测试 / 界面测试 / 兼容性测试 / 安全性测试)

Web&#xff08;性能测试 / 界面测试 / 兼容性测试 / 安全性测试&#xff09; 一、Web性能测试&#xff1a;&#xff08;压力测试、负载测试、连接速度测试&#xff09;1、压力测试&#xff1a;      并发测试 &#xff08;如500人同时登录邮箱&#xff09; 2、负载测试…

手机开启应急预警通知 / 地震预警

前言 安卓手机在检测到地震时&#xff0c;将发送地震预警通知&#xff0c;但此设置是默认关闭的&#xff0c;原因是以防引发用户恐慌从而引发安全问题&#xff0c;且开启此设置需要完成指引教程&#xff0c;因此默认关闭此设置。下文介绍如何开启此设置。 开启方法 华为手机开…

layui的基本使用-日期控件的业务场景使用入门实战案例一

效果镇楼; 1 前端UI层面; <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" conten…

SuperMap GIS基础产品云GIS FAQ集锦(5)

SuperMap GIS基础产品云GIS FAQ集锦&#xff08;5&#xff09; 【iServer】如何开启密码防暴力破解&#xff1f; 【解决办法】管理员可以在“安全配置”页面设置是否启用防暴力破解设置&#xff08;默认未启用&#xff09;&#xff0c;并可自定义修改锁定周期、允许失败次数等参…

flutter-第三方组件

卡片折叠 stacked_card_carousel 扫一扫组件 qr_code_scanner 权限处理组件 permission_handler 生成二维码组件 pretty_qr_code 角标组件 badges 动画组件 animations app更新 app_installer 带缓存的图片组件 cached_network_image 密码输入框 collection 图片保存 image_g…

Kubernetes集群部署上篇(安装部署,但是集群网络未部署)

第四阶段 时 间&#xff1a;2023年8月9日 参加人&#xff1a;全班人员 内 容&#xff1a; Kubernetes集群部署上篇 目录 一、Kubernetes部署方式 &#xff08;一&#xff09;minikube &#xff08;二&#xff09;二进制包 &#xff08;三&#xff09;Kubeadm Kubea…

centos7.9究极法-基础篇

centos7.9 前言Linux发行版本帮助命令man命令help命令 文件目录管理命令ls命令pwd命令cd命令mkdir命令cp命令scp命令rm命令mv命令chmod命令chown命令 文本内容管理命令cat命令echo命令less命令tail命令 用户和组管理命令useradd命令userdel命令passwd命令usermod命令groupadd命…

Apache DolphinScheduler 3.1.8 版本发布,修复 SeaTunnel 相关 Bug

近日&#xff0c;Apache DolphinScheduler 发布了 3.1.8 版本。此版本主要基于 3.1.7 版本进行了 bug 修复&#xff0c;共计修复 16 个 bug, 1 个 doc, 2 个 chore。 其中修复了以下几个较为重要的问题&#xff1a; 修复在构建 SeaTunnel 任务节点的参数时错误的判断条件修复 …

高德地图导览手绘图制作

&#x1f680; 本文主要讲解如何使用高德地图进行手绘图制作&#xff0c;一般用于景区导览地图制作&#xff0c;使用户更加生动、形象的去了解整个景区 主要讲解整图加载及瓦片分片加载&#xff0c;以Vue3为例 配置高德地图相关依赖 下载依赖 cnpm i amap/amap-jsapi-loader…

[ISITDTU 2019EasyPHP]使用异或webshell

文章目录 [ISITDTU 2019EasyPHP]使用异或webshell解题总结 [ISITDTU 2019EasyPHP]使用异或webshell 解题 index.php <?php highlight_file(__FILE__);$_ $_GET[_]; if ( preg_match(/[\x00- 0-9\"$&.,|[{_defgops\x7F]/i, $_) )die(ros will not do it);if ( …

8月9日,每日信息差

1、优酷申请注册「妙鸭相机」商标&#xff0c;阿里云为妙鸭相机提供算力支持&#xff0c;“妙鸭相机”已在阿里云上进行紧急扩容&#xff0c;以应对暴涨数百倍的算力需求 2、苹果或于9月12日发布iPhone 15 3、我国首条直通中越边境高铁开始铺轨&#xff0c;在广西防城港市境内…

【java】【高级拓展1】常见算法正则表达式异常

目录 1 算法 1.1 简单认识算法 1.2 常见算法 - 排序算法 1.2.1 冒泡排序 1.2.2 选择排序 1.3 常见算法-查找算法 1.3.1 基本查询&#xff08;顺序查找&#xff09;不好&#xff08;性能不好&#xff09; 1.3.2 二分查找&#xff08;折半查找&#xff09; 2 正则表达式 …