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

目录

算法类型

算法比较

稳定性描述

插入排序

选择排序

冒泡排序

希尔排序

堆排序

快速排序

霍尔排序(递归)

挖坑法(递归)

双指针(递归)

快排(非递归)

归并排序

计数排序

总结(速度比较)


算法类型

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

算法比较

稳定性描述

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

插入排序

// 插入排序
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个数

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

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

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

相关文章

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

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

ChatGPT交卷2024年高考新课标I卷语文关于AI方面的作文试题

2024年新课标I卷作文试题&#xff1a; 阅读下面的材料&#xff0c;根据要求写作。&#xff08;60分&#xff09; 随着互联网的普及、人工智能的应用&#xff0c;越来越多的问题能很快得到答案。那么&#xff0c;我们的问题是否会越来越少&#xff1f; 以上材料引发了你怎样的…

CarSim车辆运动轨迹绘制

CarSim车辆运动轨迹绘制 CarSim中与车辆位置有关的信息分别为Xo和Yo 输出到Simulink中 导入到工作空间中保存&#xff0c;low_carsim_path.mat &#xff0c;绘制结果曲线&#xff0c;low_carsim_path_comp.m data csvread(low_two_path.csv,1,0); low_two_path_x data(:,1)…

【FAS】《CN103106397B》

原文 CN103106397B-基于亮瞳效应的人脸活体检测方法-授权-2013.01.19 华南理工大学 方法 / 点评 核心方法用的是传统的形态学和模板匹配&#xff0c;亮点是双红外发射器做差分 差分&#xff1a;所述FPGA芯片控制两组红外光源&#xff08;一近一远&#xff09;交替亮灭&…

DVWA-XSS(Reflected)

反射型XSS可以用来窃取cookie Low 输入1111进行测试&#xff0c;发现1111被打印 输入<script>alert(document.cookie)</script>&#xff0c;出现弹窗&#xff0c;获得cookie Medium 查看后端代码&#xff0c;发现对<script>进行了转义&#xff0c;但是…

codeforces round 949 div2

A Turtle and Piggy Are Playing a Game 题目&#xff1a; 思路&#xff1a;输出2的幂次b使得2^b为最大的不超过x的数 代码&#xff1a; #include <iostream>using namespace std;const int N 2e5 10;void solve() {int l, r;cin >> l >> r;if(r % 2) …

大小堆运用巧解数据流的中位数

​​​​​​​​​​ 一、思路 我们将所有数据平分成两份&#xff0c;前面那一部分用小堆来存&#xff0c;后面的部分用大堆来存&#xff0c;这样我们就能立刻拿到中间位置的值。 如果是奇数个数字&#xff0c;那么我们就将把中间值放在前面的大堆里&#xff0c;所以会有两种…

华为设备动态路由OSPF(单区域+多区域)实验

动态路由OSPF的配置 OSPF分类两种情况&#xff1a;单区域 多区域路由 OSPF单区域路由配置 OSPF&#xff1a;开放最短路径优先的路由协议。属于大型动态路由协议&#xff0c;适用于中大型的园区网。 网络拓扑&#xff1a; 配置步骤&#xff1a; 1.完成基本配置&#xff08;略&a…

代码随想录算法训练营第30天|回溯复习篇

回溯基础理论 1.回溯的本质是利用递归进行暴力搜索&#xff0c;将符和条件的结果集搜索出来 2.回溯法常见的问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合排列问题&#xff1a;N个数按一定规则全排列&#xff0c;有几种排列方式切割问题&#x…

fastadmin/thinkPHPQueue消息队列详细教程

thinkphp-queue 是thinkphp 官方提供的一个消息队列服务,它支持消息队列的一些基本特性: 消息的发布,获取,执行,删除,重发,失败处理,延迟执行,超时控制等队列的多队列, 内存限制 ,启动,停止,守护等消息队列可降级为同步执行1、通过composer安装thinkPHP消息队列 …

kafka-消费者-指定offset消费(SpringBoot整合Kafka)

文章目录 1、指定offset消费1.1、创建消费者监听器‘1.2、application.yml配置1.3、使用 Java代码 创建 主题 my_topic1 并建立3个分区并给每个分区建立3个副本1.4、创建生产者发送消息1.4.1、分区0中的数据 1.5、创建SpringBoot启动类1.6、屏蔽 kafka debug 日志 logback.xml1…

算法003:快乐数

这道题采用快慢双指针的方法。 为了弄清楚这个题到底是要我们干嘛&#xff0c;我们把整个过程类比一下&#xff1a; 不管是n19还是n2&#xff0c;我们都把它当成一种判断链表是否有环的方式。 对于n19&#xff0c;题干是这样解释的&#xff1a; 我们把它当成链表&#xff0c…

如何挑选最适合你的渲染工具

随着技术的发展&#xff0c;云渲染平台逐渐成为设计师、动画师、影视制作人员等创意工作者的得力助手。然而&#xff0c;市场上的云渲染平台种类繁多&#xff0c;如何选择最适合自己的渲染工具成为了一个需要认真考虑的问题。 在挑选适合自己的云渲染工具时&#xff0c;我们需…

YOLOv10涨点改进:原创自研 | GhostNet融合 | 从廉价的操作中生成更多的特征图

文章目录 GhostNet理论基础实验部分改进方案新增yolov10s-ghost.yaml文件代码运行GhostNet理论基础 Ghost Module是一种模型压缩的方法,即在保证网络精度的同时减少网络参数和计算量,从而提升计算速度(speed),降低延时(latency)。Ghost 模块可以代替现有卷积网络中的每…

OpenAI模型规范概览

这是OpenAI对外分享的模型规范文档&#xff08;Model Spec&#xff09;&#xff0c;它定义了OpenAI希望在API接口和ChatGPT&#xff08;含GPT系列产品&#xff09;中模型的行为方式&#xff0c;这也是OpenAI超级对齐团队奉行的行为准则&#xff0c;希望能对国内做RLHF的同学有帮…

.Net实现SCrypt Hash加密

方案1 &#xff08;加密后存储“算法设置”、“盐(随机值)”、“Hash值”&#xff0c;以“$”分隔&#xff09;&#xff1a; //Nuget引入SCrypt.NET库 using Org.BouncyCastle.Crypto.Generators; using Scrypt; using System; using System.Security.Cryptography; namespace …

Apache OFBiz 路径遍历导致RCE漏洞复现(CVE-2024-36104)

0x01 产品简介 Apache OFBiz是一个电子商务平台,用于构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类应用系统。是美国阿帕奇(Apache)基金会的一套企业资源计划(ERP)系统。该系统提供了一整套基于Java的Web应用程序组件和工具。 0x02 漏洞概…

90后机器人创业者再获10亿元融资,为精密传动行业注入新动力!

据了解&#xff0c;一位90后机器人创业者再次获得近10亿元人民币的融资&#xff0c;这一消息在精密传动行业引起了广泛关注。 杭州宇树科技有限公司&#xff08;简称“宇树”&#xff09;&#xff0c;2024年春节前完成了B2轮融资&#xff0c;融资近10亿元人民币&#xff0c;本轮…

pyqt5 tablewidget实现excel拖曳填充

代码主要涉及鼠标事件和绘图&#xff0c;selectionModel&#xff0c;selectedIndexes。 import sys from PyQt5.QtCore import QPoint, Qt, QCoreApplication, pyqtSlot from PyQt5.QtGui import QBrush, QPixmap, QColor, QPainter,QIcon,QPolygon from PyQt5.QtWidgets imp…

【Java】解决Java报错:ClassCastException

文章目录 引言1. 错误详解2. 常见的出错场景2.1 错误的类型转换2.2 泛型集合中的类型转换2.3 自定义类和接口转换 3. 解决方案3.1 使用 instanceof 检查类型3.2 使用泛型3.3 避免不必要的类型转换 4. 预防措施4.1 使用泛型和注解4.2 编写防御性代码4.3 使用注解和检查工具 5. 示…