007+limou+C语言基础排序算法(上)

news/2024/11/17 21:39:21/

0.前言

您好这里是limou3434的一篇博文,感兴趣可以看看我的其他内容。

排序算法简单理解就是:一串数组经过排序算法后得到有序的数组。排序算法在不同应用场景有不同的效果,因此我们有必要了解一些基础的排序算法。

而本次我给您带来的是一些基础的排序算法,主要涉及四种排序算法:插入排序、选择排序、交换排序、归并排序。

在这里插入图片描述

1.插入排序

1.1.直接插入排序

1.1.1.排序思想

在[0,end]有序的前提下,保证插入tmp后依旧有序。

1.1.2.具体code与test用例

#include <stdio.h>
void InsertSort(int* arr, int arrSize)
{for(int i = 0; i < arrSize; i++){int end = i-1;int tmp = arr[i];while (end >= 0){if (tmp < arr[end]){arr[end + 1] = arr[end];end--;}else{break;}}arr[end + 1] = tmp;}
}
void test(void)
{int arr[10];srand((unsigned)time(0));printf("排序前:");for (int i = 0; i < 10; i++){arr[i] = rand() % 10;printf("%d ", arr[i]);}printf("\n排序后:");InsertSort(arr, 10);for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}
}
int main()
{test();return 0;
}

1.1.3.算法复杂度分析

在最坏情况下,每次tmp进来都需要把索引[0,end]的数据往后挪动,总共挪动的次数是“0+1+2+…+(n-1)=((0+n-1)*(n))/2”,即时间复杂度为O(n^2)。

1.2.希尔排序

1.2.1.排序思想

希尔排序的思想就是:先对数据进行预排序,然后进行直接插入排序。

详细的思路就是:假设有一个值gap,将数据间隔gap分为一组,然后对每一组分别进行直接插入排序,因此这里可以复用之前的直接插入排序代码。

写希尔排序最好先写直接插入排序,然后改写为希尔排序(就是把1改成gap),最后得到预排序数组。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2.2.具体code与test用例

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <stdio.h>
#define SIZE 100
void InsertSort(int* arr, int arrSize)//插入排序的实现
{for (int i = 0; i < arrSize; i++){int end = i - 1;int tmp = arr[i];while (end >= 0){if (tmp < arr[end]){arr[end + 1] = arr[end];end--;}else{break;}}arr[end + 1] = tmp;}
}
void ShellSort(int* arr, int arrSize)//希尔排序的实现
{//0.gap的最大意义在于:让最大的数更快跳到后面,让更小的数更快跳到前面//0.1.gap越大越不接近有序,但是跳得快//0.2.gap越小越接近有序,特别当gap=1时,其效果等价于直接插入排序//1.写法一(单组单排)//for (int gap = arrSize/2; gap >= 1; gap /= 2)//1.3.控制gap的大小//{//	for (int j = 0; j < gap; j++)//1.2.分别使用“直接插入排序”排序gap组个数组//	{//		for (int i = j; i < arrSize; i += gap)//		{//			//1.1.某一次一组的“直接插入排序”//			int end = i - gap;//			int tmp = arr[i];//			while (end >= 0)//			{//				if (tmp < arr[end])//				{//					arr[end + gap] = arr[end];//					end -= gap;//				}//				else//				{//					break;//				}//			}//			arr[end + gap] = tmp;//		}//	}//}//2.写法二(多组同排,但是效率没有变化)int gap = arrSize;while(gap > 1)//2.3.控制gap的大小(注意这里得入口不能写等于,会因为条件“gap=gap/3+1”而死循环,这是代码设计导致的){gap = gap / 3 + 1;//加1是为了保证最后一次是1,能用上gap=1的直接插入排序for (int i = 0; i < arrSize; i++)//2.2.每组只取一个元素排序{//2.1.“直接插入排序”代码 int end = i - gap;int tmp = arr[i];while (end >= 0){if (tmp < arr[end]){arr[end + gap] = arr[end];end -= gap;}else{break;}}arr[end + gap] = tmp;}}
}
void Test1()
{int arr[SIZE] = { 0 };for (int i = 0; i < SIZE; i++){arr[i] = rand() % 10;}for (int i = 0; i < SIZE; i++){printf("%d ", arr[i]);}printf("\n");printf("InsertSort() :");InsertSort(arr, SIZE);for (int i = 0; i < SIZE; i++){printf("%d ", arr[i]);}printf("\n\n");
}
void Test2()
{int arr[SIZE] = { 0 };for (int i = 0; i < SIZE; i++){arr[i] = rand() % 10;}for (int i = 0; i < SIZE; i++){printf("%d ", arr[i]);}printf("\n");printf("ShellSort()  :");ShellSort(arr, SIZE);for (int i = 0; i < SIZE; i++){printf("%d ", arr[i]);}printf("\n\n");
}
int main()
{Test1();Test2();return 0;
}

1.2.3.算法复杂度分析

希尔排序的算法复杂度分析不能只看for循环,这是极其错误的,一个典型的例子就是:我们在写希尔排序的时候,写了“四层循环”和“三层循环”的方法,但是两种方法的效果是一样的。

在这里插入图片描述

以博主的数学知识是没有办法进行计算的(貌似在数学界也有些问题没有被解决),所以暂时跳过吧。我们只需要记住希尔排序的时间复杂度范围在[O(N*(log(2)(N))2),O(N2)]之间即可,整体认为希尔排序的时间复杂度是O(N^1.3)即可。

2.选择排序

2.1.直接选择排序

2.1.1.排序思想

从一个待排序列中选出最小/最大的数,然后将最小/最大的数和待排序列中的第一个数/最后一个数交换,不断重复。

但是这样效率太低,可以优化一下:从一个待排序列中选出最小的数和最大的数,然后将最小的数和最大的数分别和待排序列中的第一个数和最后一个数交换,不断重复,效率好了一倍。

2.1.2.具体code与test样例

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <stdio.h>
#define SIZE 10
void _Swap(int* px, int* py)
{int tmp = *px;*px = *py;*py = tmp;
}
void SelectSort(int* arr, int arrSize)
{int begin = 0, end = arrSize - 1;while (begin < end){int maxi = begin;int mini = end;for (int i = begin; i <= end; i++){if (arr[i] > arr[maxi])//选出最大数的下标{maxi = i;}if (arr[i] < arr[mini])//选出最小数的下标{mini = i;}}_Swap(&arr[begin], &arr[mini]);if (begin == maxi)//处理特殊情况{maxi = mini;}_Swap(&arr[end], &arr[maxi]);begin++;end--;}
}
int main()
{int arr[SIZE] = { 0 };for (int i = 0; i < SIZE; i++){arr[i] = rand() % 10;}for (int i = 0; i < SIZE; i++){printf("%d ", arr[i]);}printf("\n");printf("SelectSort() :");SelectSort(arr, SIZE);for (int i = 0; i < SIZE; i++){printf("%d ", arr[i]);}printf("\n\n");return 0;
}

http://www.ppmy.cn/news/687128.html

相关文章

在 javascript 中构建字符串

文章目录 在 JavaScript 中构建字符串在 JavaScript 中使用 和 concat() 构建字符串在 JavaScript 中使用 push() 和 join() 构建字符串 本文将通过不同的代码示例讨论使用连接运算符和 JavaScript 中的一些内置方法生成或构建字符串。 在 JavaScript 中构建字符串 要在 Java…

上手有毒 前方高能北通K1手游机械键盘测评体验

​ ​ 前言 话说在连续NNN天后&#xff0c;终于第一次在360试用平台中签&#xff0c;那个心情万分激动&#xff08;害我晚上回去买了彩票&#xff0c;至于结果大家都知道了&#xff09;&#xff0c;这次也好好的看了一下北通&#xff0c;这是北通第一款手游机械键盘&#xf…

北通 战戟 BTP-2118

今天上午和文兄&#xff0c;带鱼&#xff0c;玉鹏一起去新大地配新机箱&#xff0c;顺路&#xff0c;花80大洋购入 北通 战戟 BTP-2118 一块&#xff0c;白色&#xff0c;左边的按键比较硬&#xff0c;非常满意&#xff0c;开极品时不会过于灵敏&#xff0c;之前看到的几款&am…

ubuntu/linux 北通无线游戏手柄不识别

1.现象 1.开发板无法识别北通无线游戏手柄 北通蝙蝠BD2A无线游戏手柄 lsusb Bus 007 Device 003: ID 045e:028e Microsoft Corp. Xbox360 Controller ls /dev/input by-id by-path event0 event1 event2 event3 event4 event5 event6 没有识别到js0设备 2.ubuntu系统可以到…

Python小波包特征提取能量熵

Python小波包特征提取能量熵 小波包分析是一种基于小波函数的信号分析方法&#xff0c;在特征提取中有着广泛的应用。能量熵是小波包分析中一种常用的特征参数&#xff0c;用于描述信号分布的集中性程度。本文将介绍Python中如何使用小波包进行特征提取&#xff0c;并计算能量…

获取Layui iframe页面的url参数

弹出layui iframe页面 layer.open({type: 2, // iframe层skin: layer-ext-blue,title: 弹出窗口,content: "click?hrefcatalogConfig/addCatalog?param1" param1 "&param2" param2, // 弹出的iframe页面地址catalogConfig/addCatalogarea: [1224…

MC起床战争

1.02更新&#xff1a;增加弓箭、死斗模式。&#xff08;提前声明&#xff1a;本版本超吃配置&#xff0c;请确保使用时电脑不烫&#xff09; 代码 #include<algorithm> #include<fstream> #include<iostream> #include<stdio.h> #include<cstdio&…

Minecraft我的世界服务器配置5人/10人/50人玩家搭建mc服务器

我的世界服务器租用10人mc服务器配置如何选&#xff1f;我的世界5人玩家选择腾讯云轻量2核2G4M服务器、Minecraft服务器10人玩家2核4G6M服务器配置、mc服务器20人选4核8G10M、我的世界mc服务器50人或100人选8核16G14M&#xff0c;腾讯云轻量应用服务器搭建我的世界mc服务器&…