C语言实现常见O(N^2)的排序算法

目录

1.排序的概念及常见排序算法

1.1排序的概念

1.2常见的排序算法

2.常见O(N^2)排序算法的实现

2.1插入排序

2.1.1基本思想

2.1.2直接插入排序

2.1.2.1直接插入排序的特性

2.1.2.2直接插入排序算法实现

2.2选择排序

2.2.1基本思想

2.2.2直接选择排序

2.2.2.1直接选择排序的特性

2.2.2.2直接选择排序算法实现

2.3冒泡排序

2.3.1基本思想

2.3.2冒泡排序的特性总结


1.排序的概念及常见排序算法

1.1排序的概念

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性 :假定在待排序的记录序列中,存在多个具有相同的关键字(相同的数据)的记录,若经过排序,这些记录的相对次序保持不变 ,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

内部排序:数据元素全部放在内存中的排序。

外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不断地在内外存之间移动数据的排序。

1.2常见的排序算法

2.常见O(N^2)排序算法的实现

2.1插入排序

2.1.1基本思想

**把待排序的元素按大小关系逐个插入到一个已经排好序的有序序列中,直到所以的元素插入完为止,得到一个新的有序序列。**类比于平时玩扑克牌时理牌的思想。

2.1.2直接插入排序

当插入第i(i>=1)个元素时,前面的array0,array1,...,arrayi-1已经排好序,此时用arrayi的排序码与arrayi-1,arrayi-2,...的排序码顺序进行比较,找到插入位置即将arrayi插入,原来位置上的元素顺序后移。

2.1.2.1直接插入排序的特性

(1)元素集合越接近有序,直接插入排序算法的时间效率越高(比较的次数越少),最好情况为有序的情况,时间复杂度会优化为O(N)。

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

(3)空间复杂度:O(1)。

(4)稳定性:稳定。

2.1.2.2直接插入排序算法实现
cpp 复制代码
void InsertSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)// end最后一个位置为n-2
	{
		int end = i;
		int tmp = a[end + 1]; //先保存end+1位置的值,以免移动时被覆盖
		//[0, end]有序,end+1位置的值插入然后保持有序
		while (end >= 0) //如果是循环条件不满足跳出的循环,则表示tmp比所以值都小,此时的end为-1
		{
			if (a[end] > tmp)
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				//a[end + 1] = tmp; 这行代码放到循环外是为了兼容tmp为最小值不满足循环条件跳出循            
                //环的情况
				break;
			}
		}
		a[end + 1] = tmp; 
	}
}

2.2选择排序

2.2.1基本思想

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

2.2.2直接选择排序

1.在元素集合 arrayi--arrayn-1 中选择关键码最大 ( 小 ) 的数据元素。
2.若它不是这组元素中的最后一个 ( 第一个 ) 元素,则将它与这组元素中的最后一个(第一个)元素交换。
3.在剩余的 arrayi--arrayn-2 ( arrayi+1--arrayn-1 )集合中,重复上述步骤,直到集合剩余 1 个元素。

2.2.2.1直接选择排序的特性
  1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用。

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

  3. 空间复杂度:O(1)

  4. 稳定性:不稳定

2.2.2.2直接选择排序算法实现

该算法实现每次遍历从数组中找出最大的数和最小的数,分别放在最后和最前面。

cpp 复制代码
void SelectSort(int* a, int n)
{
    int begin = 0, end = n - 1;
	while (begin < end)
	{
		int mini = begin, maxi = begin;
		for (int i = begin + 1; i <= end; ++i)
		{
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
			if (a[i] < a[mini])
			{
				mini = i;
			}
		}
		Swap(&a[begin], &a[mini]);
		if (begin == maxi)    //如果第一个位置是最大的数,修正maxi
		{
			maxi = mini;
		}

		Swap(&a[end], &a[maxi]);
		++begin;
		--end;
	}
}

2.3冒泡排序

2.3.1基本思想

从开始比较两个相邻的元素,把大的元素放在后面,再依次和该元素后面元素一一比较,单趟结束之后把最大的数冒到最后。

2.3.2冒泡排序的特性总结

  1. 冒泡排序是一种非常容易理解的排序。
  2. 时间复杂度:O(N^2)。
  3. 空间复杂度:O(1)。
  4. 稳定性:稳定。
相关推荐
秋941 分钟前
Go语言(Golang)开发工程师全景解析:岗位职责·语言优势与使用场景·各城市薪资·发展前景·高考志愿填报(2026版)
开发语言·golang·高考
十月的皮皮1 小时前
C语言学习笔记20260606- 求月份天数三种写法
c语言·笔记·学习
huangdong_2 小时前
1688商品图片采集技术解析:登录态处理与SKU图自动分类
开发语言
chase_my_dream2 小时前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试
Cloud_Shy6182 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 30 - 32)
开发语言·人工智能·笔记·python·学习方法
caimouse2 小时前
Reactos 第 5 章 进程与线程 — 5.8 Windows 的 APC 机制
c语言·windows
天佑木枫3 小时前
15天Python入门系列 · 序
开发语言·python
宋拾壹4 小时前
同时添加多个类目
android·开发语言·javascript
凡人叶枫4 小时前
Effective C++ 条款04:确定对象被使用前已先被初始化
java·linux·开发语言·c++·嵌入式开发
用户484526255824 小时前
数组分区和荷兰国旗只差一个条件:稳定性
排序算法