C语言数据结构(排序算法总结)

news2025/1/17 0:04:21

目录

算法类型

算法比较

稳定性描述

插入排序

选择排序

冒泡排序

希尔排序

堆排序

快速排序

霍尔排序(递归)

挖坑法(递归)

双指针(递归)

快排(非递归)

归并排序

计数排序

总结(速度比较)


算法类型

插入排序,选择排序,冒泡排序,希尔排序,堆排序,快速排序(递归霍尔,挖坑,双指针,非递归),归并排序(递归,非递归),计数排序

算法比较

稳定性描述

数组相同大小元素顺序是否发生变化

插入排序

// 插入排序
void InsertSort(int* a, int n) {
	int i,tmp,j;
	for (i = 0; i < n - 1; i++) {
		tmp = a[i + 1];
		for (j = i; j >= 0; j--) {
			if (a[j] > tmp)
				a[j + 1] = a[j];
			else
				break;
		}
		a[j + 1] = tmp;
	}
}

特性:

越有序越快,算法稳定

时间复杂度:

O(N^2)

空间复杂度:

O(1)

选择排序

// 选择排序
void SelectSort(int* a, int n) {
	int i, j, max, min,mid=n/2;
	for (i = 0; i < mid; i++) {
		max = min = i;
		for (j = i; j < n - i; j++) {
			if (a[j] > a[max])
				max = j;
			if (a[j] < a[min])
				min = j;
		}
		swap(&a[i], &a[min]);
		if (max == i)
			max = min;
		swap(&a[n - i - 1], &a[max]);
	}
}

特性:

效率比较稳定,算法不稳定(看自己写的算法取值)

时间复杂度:

O(N^2)

空间复杂度:

O(1)

冒泡排序

// 冒泡排序
void BubbleSort(int* a, int n) {
	int i, j;
	for (i = 0; i < n - 1; i++) {
		for (j = 0; j < n - i - 1; j++) {
			if (a[j] > a[j + 1])
				swap(&a[j], &a[j + 1]);
		}
	}
}

特性:

算法稳定,效率一般,有教学意义

时间复杂度:
O(N^2)

空间复杂度:

O(1)

希尔排序

void ShellSort(int* a, int n) {
	int i, j, gap=n, tmp,k;
	while (gap > 1) {
		gap = gap / 3 + 1;
		for (i = 0; i < gap; i++) {
			for (k = i; k < n - gap; k += gap) {
				tmp = a[k + gap];
				for (j = k; j >= 0; j -= gap) {
					if (a[j] > tmp)
						a[j + gap] = a[j];
					else
						break;
				}
				a[j + gap] = tmp;
			}
		}
	}
}

特性:

算法非常不稳定,无法预测

是插入排序的升级版,针对无序情况

时间复杂度:
O(N^1.3)

空间复杂度:

O(1)

堆排序

// 堆排序
void AdjustDown(int* a, int n, int root) {//大堆
	int parent=root,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]);
		else
			break;
		parent = child;
		child = child * 2 + 1;
	}
}
void HeapSort(int* a, int n) {
	int i;
	for (i = (n - 1 - 1) / 2; i >= 0; i--)
		AdjustDown(a, n, i);
	for (i = n - 1; i > 0; i--) {
		swap(&a[i], &a[0]);
		AdjustDown(a, i, 0);
	}
}

特性:

排序时间比较稳定,算法不稳定

时间复杂度:

向上整理成堆:O(NlogN)

向下整理成堆堆:O(N)

堆排序:O(NlogN)

空间复杂度:

O(1)

快速排序

特性:

算法不稳定,越有序越慢

时间复杂度:

O(NlogN)

空间复杂度:

O(1)

优化:

越有序越慢,我们可以找到一个值不是最大也不是最小,与首元素进行交换提升效率

在元素个数比较少时使用插入排序

霍尔排序(递归)

// 快速排序递归实现
// 快速排序hoare版本
void PartSort1(int* a, int left, int right) {
	if (left >= right)
		return;
	int begin = left, end = right,key=left;
	while (begin < end) {
		while (begin<end&&a[end] >= a[key])
			end--;
		while (begin<end&&a[begin] <= a[key])
			begin++;
		swap(&a[begin], &a[end]);
	}
	swap(&a[key], &a[end]);
	key = begin;
	PartSort1(a, left, key - 1);
	PartSort1(a, key + 1, right);
}

挖坑法(递归)

// 快速排序挖坑法
void PartSort2(int* a, int left, int right) {
	if (left >= right)
		return;
	int begin = left, end = right, tmp = a[left];
	while (begin < end) {
		while (begin<end&&a[end] >= tmp)
			end--;
		a[begin] = a[end];
		tmp = a[end];
		while (begin<end&&a[begin] <= tmp)
			begin++;
		a[end] = a[begin];
		tmp = a[end];
	}
	a[end] = tmp;
	PartSort2(a, left, begin - 1);
	PartSort2(a, end + 1, right);
}

双指针(递归)

void QuickSort(int* a, int left, int right) {
	if (left >= right)
		return;
	int cur = left + 1, pre = left;
	while (cur <= right) {
		if (a[cur] < a[left] && ++pre < cur)
			swap(&a[cur], &a[pre]);
		cur++;
	}
	swap(&a[left], &a[pre]);
	QuickSort(a, pre + 1, right);
	QuickSort(a, left, pre - 1);
}

快排(非递归)

选择一种快排方法,返回修正位置key

int PartSort3(int* a, int left, int right) {
	if (left >= right)
		return -1;
	int cur = left + 1, pre = left;
	while (cur <= right) {
		if (a[cur] < a[left] && ++pre < cur)
			swap(&a[cur], &a[pre]);
		cur++;
	}
	swap(&a[left], &a[pre]);
	return pre;
}
// 快速排序 非递归实现
void QuickSortNonR(int* a, int left, int right) {
	Stack stack;
	StackInit(&stack);
	StackPush(&stack, right);
	StackPush(&stack, left);
	while (!StackEmpty(&stack)) {
		int begin = StackTop(&stack);
		StackPop(&stack);
		int end = StackTop(&stack);
		StackPop(&stack);
		int key = PartSort3(a, begin, end);
		if (key - 1 > begin) {
			StackPush(&stack, key-1);
			StackPush(&stack, begin);
		}
		if (key + 1 < end) {
			StackPush(&stack, end);
			StackPush(&stack, key+1);
		}
	}
}

归并排序

特性:

稳定,时间复杂度也稳定

时间复杂度:

O(NlogN)

空间复杂度:

O(N)

递归

void _merge(int* a, int* tmp, int left, int right) {
	if (left >= right)
		return;
	int mid = (left + right) / 2;
	_merge(a, tmp,left, mid);
	_merge(a, tmp, mid + 1, right);
	int begin1 = left, begin2 = mid + 1,i=left;
	while (begin1 <= mid && begin2 <= right) {
		if (a[begin1] > a[begin2])
			tmp[i++] = a[begin2++];
		else
			tmp[i++] = a[begin1++];
	}
	while(begin1 <= mid)
		tmp[i++] = a[begin1++];
	while (begin2 <= right)
		tmp[i++] = a[begin2++];
	memcpy(a + left, tmp + left, sizeof(int) * (right - left + 1));
}
// 归并排序递归实现
void MergeSort(int* a, int n) {
	int* tmp = (int*)malloc(sizeof(int) * n);
	_merge(a, tmp, 0, n - 1);
	free(tmp);
	tmp = NULL;
}

非递归

// 归并排序非递归实现
void MergeSortNonR(int* a, int n) {
	int gap = 1,i,begin,*tmp=(int*)malloc(sizeof(int)*n);
	while (gap < n) {
		for (begin = 0; begin < n - gap; begin+=2*gap) {
			int begin1 = begin,end1=begin+gap-1,begin2=begin+gap,end2=begin2+gap-1;
			if (begin2 >= n)
				break;
			if (end2 >= n)
				end2 = n - 1;
			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, tmp, sizeof(int) * n);
		gap *= 2;
	}
}

计数排序

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

特性:

空间复杂度仅与最大最小数有关,只可用于排列数

数越均衡越快

时间复杂度:

O(N)//均衡的话

总结(速度比较)

先比较插入,选择,冒泡排序,放置1w个随机数

比较剩下几个排序,每个放入1000w个数

由于伪随机数非常均衡,因此相对来说计数排序效率相对来说非常高

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

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

相关文章

计算机毕业设计基于YOLOv8的头盔检测系统

1、安装Anaconda 官网下载或者哔哩哔哩有的up分享 https://www.anaconda.com/download 版本无所谓&#xff0c;安装位置不要有中文就行 2、创建环境yolov8 winR打开命令行 conda create -n yolov8 python3.9 3、打开源码 下载下来放到你想放的目录&#xff0c;直接用pyCharm或者…

华为端云一体化开发 (起步1.0)(HarmonyOS学习第七课)

官方文献&#xff1a; 为丰富HarmonyOS对云端开发的支持、实现端云联动&#xff0c;DevEco Studio推出了云开发功能&#xff0c;开发者在创建工程时选择云开发模板&#xff0c;即可在DevEco Studio内同时完成HarmonyOS应用/元服务的端侧与云侧开发&#xff0c;体验端云一体化协…

【排序】插入排序,希尔排序

前面我们讲述了冒泡排序和选择排序&#xff0c;我们本章讲的排序方法是插入排序&#xff0c;插入排序是希尔排序实现的基础函数&#xff0c;大家一定要好好理解插入排序的逻辑&#xff0c;这样才能在后面学习希尔排序的时候&#xff0c;更容易的去理解&#xff0c;我们直接开始…

Vue根据后端返回的tabList动态渲染组件信息

最近做了一个功能&#xff0c;后端根据配置信息&#xff0c;动态返回一个tabList&#xff0c;其中结构是List<String,Object> tabList; map里面的数据是 label、value 页面需要根据tablist动态渲染组件&#xff08;不同的tab都使用了组件进行了封装&#xff09; 实现效果…

[原创][Delphi多线程]TThreadedQueue的经典使用案例.

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delph…

Git介绍及应用

1.简介 Git是一个分布式版本控制器&#xff0c;通常用来对软件开发过程中的源代码文件进行管理。通过Git仓库来存储和管理这些文件&#xff0c;Git仓库分为两种&#xff1a; 本地仓库:开发人员自己电脑上的Git仓库远程仓库:远程服务器上的Git仓库 2.执行流程 3.Git代码托管服务…

NFT Insider #133:苏富比将拍卖BAYC系列NFT,Taiko创世NFT系列已上线

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members &#xff08;https://twitter.com/WHALEMembers&#xff09;、BeepCrypto &#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜…

360误删掉的文件怎么恢复?3种文件找回办法!

360是一款电脑安全辅助软件&#xff0c;可以用它来清理垃圾、查杀病毒、修复系统等。然而&#xff0c;有时文件可能会被360误认为是垃圾而自动清理&#xff0c;造成重要文件丢失&#xff0c;那么360删掉的文件怎么恢复&#xff1f;下面&#xff0c;让我们一起来看看如何恢复文件…

Java面试题:Redis持久化问题

Redis持久化问题 RDB (Redis Database Backup File) Redis数据快照 将内存中的所有数据都记录到磁盘中做快照 当Redis实例故障重启时,从磁盘读取快照文件恢复数据 使用 save/bgsave命令进行手动快照 save使用主进程执行RDB,对所有命令都进行阻塞 bgsave使用子进程执行R…

Java——面向对象进阶(一)

前言 面向对象进阶(一)&#xff1a;static&#xff0c;继承&#xff0c;this和super关键字 文章目录 一、static1.1 静态变量1.2 静态方法1.3 静态变量和静态方法在内存中 二、继承2.1 概念2.2 继承的特点和能继承什么2.3 继承中的重写2.4 this和super关键字 一、static 在 Jav…

基于拓扑漏洞分析的网络安全态势感知模型

漏洞态势分析是指通过获取网络系统中的漏洞信息、拓扑信息、攻击信息等&#xff0c;分析网络资产可能遭受的安全威胁以及预测攻击者利用漏洞可能发动的攻击&#xff0c;构建拓扑漏洞图&#xff0c;展示网络中可能存在的薄弱环节&#xff0c;以此来评估网络安全状态。 在网络安…

如何使用Vuforia AR进行增强现实技术的开发?

前言 今天是坚持写博客的第17天&#xff0c;很高兴自己可以一直坚持下来。我们今天来讲讲怎么使用Vuforia AR进行增强现实的开发。 我们需要在今天的开发中用到Vuforia AR和2018版的Unity3d 什么是Vuforia AR Vuforia AR是基于实时计算摄影机影像的位置及角度&#xff0c;并…

【Kubernetes】三证集齐 Kubernetes实现资源超卖(附镜像包)

目录 插叙前言一、思考和原理二、实现步骤0. 资料包1. TLS证书签发2. 使用 certmanager 生成签发证书3. 获取secret的内容 并替换CA_BUNDLE4.部署svc deploy 三、测试验证1. 观察pod情况2. 给node 打上不需要超售的标签【可以让master节点资源不超卖】3. 资源实现超卖4. 删除还…

吴谨言墨雨背后用真诚柱铸就爆款之路

吴谨言&#xff1a;墨雨背后&#xff0c;用真诚铸就爆款之路在繁华的娱乐圈&#xff0c;每一个成功的背后隐藏着不为人知的努力和汗水。而今天&#xff0c;我们要讲述的&#xff0c;正是这样一位用真诚和执着&#xff0c;一步步走向成功的演员——吴谨言。近日&#xff0c;一则…

古字画3d立体在线数字展览馆更高效便捷

在数字时代的浪潮中&#xff0c;大连图书馆以崭新的面貌跃然屏幕之上——3D全景图书馆。这座承载着城市文化精髓与丰富知识资源的数字图书馆&#xff0c;利用前沿的三维建模技术&#xff0c;为我们呈现了一个全新的知识世界。 随时随地&#xff0c;无论您身处何地&#xff0c;只…

python如何画函数图像

通过图像可以直观地学习函数变化、分布等规律&#xff0c;在学习函数、概率分布等方面效果显著。下面我们尝试用Python的2D绘图库matplotlib来绘制函数图像。 下面我们来实现一个简单的函数&#xff1a; 首先&#xff0c;调用matplotlib库和numpy库 import matplotlib.pyplot …

视频修复工具,模糊视频变清晰!

老旧视频画面效果差&#xff0c;视频效果模糊。我们经常找不到一个好的工具来让视频更清晰&#xff0c;并把它变成高清画质。相信很多网友都会有这个需求&#xff0c;尤其是视频剪辑行业的网友&#xff0c;经常会遇到这个问题。今天给大家分享一个可以把模糊视频修复清晰的工具…

创新指南|2个维度、3个步骤助力AI办公在企业内部顺利实施运行

AI可以提升工作质量&#xff0c;但如何在企业内部运行AI办公却可能是管理者们面临的最具挑战性的一步。众所周知&#xff0c;AI正在高速发展&#xff0c;它带给企业的好处显而易见&#xff0c;既提高了工作效率也精进了产品服务&#xff0c;然而员工对AI办公的普及却并不都是持…

Spring Boot + URule 实现可视化规则引擎,太优雅了!

Spring Boot URule 实现可视化规则引擎&#xff0c;太优雅了&#xff01; 一、背景二、介绍三、安装使用四、基础概念整体介绍库文件变量库文件常量库文件参数库文件动作库文件规则集向导式规则集脚本式规则集 决策表其他 五、运用场景六、总结 一、背景 前段时间&#xff0c…

释放视频潜力:Topaz Video AI for mac/win 一款全新的视频增强与修复利器

在数字时代&#xff0c;视频已经成为我们记录生活、分享经历的重要方式。然而&#xff0c;有时候我们所拍摄的视频可能并不完美&#xff0c;可能存在模糊、噪点、抖动等问题。这时候&#xff0c;就需要一款强大的视频增强和修复工具来帮助我们提升视频质量&#xff0c;让它们更…