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排序的概念

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

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

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

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

1.2常见的排序算法

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

2.1插入排序

2.1.1基本思想

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

2.1.2直接插入排序

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

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.在元素集合 array[i]--array[n-1] 中选择关键码最大 ( 小 ) 的数据元素。
2.若它不是这组元素中的最后一个 ( 第一个 ) 元素,则将它与这组元素中的最后一个(第一个)元素交换。
3.在剩余的 array[i]--array[n-2] ( array[i+1]--array[n-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. 稳定性:稳定。
相关推荐
☺����9 分钟前
实现自己的AI视频监控系统-第一章-视频拉流与解码2
开发语言·人工智能·python·音视频
染翰28 分钟前
lua入门以及在Redis中的应用
开发语言·redis·lua
王者鳜錸39 分钟前
PYTHON让繁琐的工作自动化-函数
开发语言·python·自动化
兔老大RabbitMQ1 小时前
git pull origin master失败
java·开发语言·git
tt5555555555551 小时前
C/C++嵌入式笔试核心考点精解
c语言·开发语言·c++
xiao助阵1 小时前
python实现梅尔频率倒谱系数(MFCC) 除了傅里叶变换和离散余弦变换
开发语言·python
科大饭桶2 小时前
C++入门自学Day14-- Stack和Queue的自实现(适配器)
c语言·开发语言·数据结构·c++·容器
扛麻袋的少年3 小时前
7.Kotlin的日期类
开发语言·微信·kotlin
钢铁男儿3 小时前
Python 正则表达式实战:解析系统登录与进程信息
开发语言·python·正则表达式
野生技术架构师4 小时前
2025年中高级后端开发Java岗八股文最新开源
java·开发语言