【排序算法】一、排序概念和直接插入排序(C/C++)

「前言」文章内容是排序算法之直接插入排序的讲解。(所有文章已经分类好,放心食用)

「归属专栏」排序算法

「主页链接」个人主页

「笔者」枫叶先生(fy)

目录

一、排序概念的介绍

排序的概念

  • 排序 :所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作
  • 稳定性 :假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的
  • 内部排序:数据元素全部放在内存中的排序
  • 外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内存和外存之间移动数据的排序

常见的排序算法

二、直接插入排序

2.1 原理

直接插入排序是一种简单直观的排序算法,它的基本思想是将一个元素插入到已经排好序的部分数组中,从而使得数组保持有序。[基于数组(顺序表)的结构进行排序)]

例如,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序。按照此法对所有元素进行插入,直到整个序列有序

具体步骤如下:

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5

例如,对数组[4, 2, 5, 1, 6, 3]进行排序,使用直接插入排序,如下:(升序)

动图演示:(数据不和上面相同)

时间、空间复杂度

  • 时间复杂度最好情况下为O(N),此时待排序列为升序,或者说接近升序
  • 时间复杂度最坏情况下为O(N^2),此时待排序列为逆序,或者说接近逆序
  • 总的来说,直接插入排序的时间复杂度为O(N^2)
  • 在原有的数组上操作,空间复杂度为O(1)

2.2 代码实现(C/C++)

C语言代码如下:(升序)

cpp 复制代码
// 直接插入排序
void InsertSort(int* arr, int n) // arr:需要排序的数组; n:数组的大小
{
	for (int i = 0; i < n-1; ++i) // 达到n-1时,数组已经有序,无需再遍历最后一次,避免多余的循环
	{
		// [0, end]有序,把end+1位置的值插入,保持有序
		int end = i; // 记录有序序列的最后一个下标
		int tmp = arr[end + 1]; // 保存等待插入的值

		while (end >= 0) 
		{
			if (arr[end] > tmp) // arr[end]比要插入的数大,向后移动
			{
				arr[end + 1] = arr[end]; // 向后移,进行覆盖,tmp已经保存被覆盖的值
				--end; // 迭代
			}
			else // arr[end]比要插入的数小,已有序,跳出循环
			{
				break;
			}
		}
		arr[end + 1] = tmp; // 进行插入
	}
}

C++代码:(升序)

cpp 复制代码
// 直接插入排序
void InsertSort(vector<int>& arr)
{
	int n = arr.size();
	for (int i = 0; i < n - 1; ++i) // 达到n-1时,数组已经有序,无需再遍历最后一次,避免多余的循环
	{
		// [0, end]有序,把end+1位置的值插入,保持有序
		int end = i; // 记录有序序列的最后一个下标
		int tmp = arr[end + 1]; // 保存等待插入的值

		while (end >= 0)
		{
			if (arr[end] > tmp) // arr[end]比要插入的数大,向后移动
			{
				arr[end + 1] = arr[end]; // 向后移,进行覆盖,tmp已经保存被覆盖的值
				--end; // 迭代
			}
			else // arr[end]比要插入的数小,已有序,跳出循环
			{
				break;
			}
		}
		arr[end + 1] = tmp; // 进行插入
	}
}

2.3 特性总结

直接插入排序的特性总结

  • 元素集合越接近有序,直接插入排序算法的时间效率越高
  • 时间复杂度:O(N^2)
  • 空间复杂度:O(1),它是一种稳定的排序算法
  • 稳定性:稳定

--------------------- END ----------------------

cpp 复制代码
「 作者 」 枫叶先生
「 更新 」 2024.1.9
「 声明 」 余之才疏学浅,故所撰文疏漏难免,
          或有谬误或不准确之处,敬请读者批评指正。
相关推荐
唐诺3 小时前
几种广泛使用的 C++ 编译器
c++·编译器
XH华3 小时前
初识C语言之二维数组(下)
c语言·算法
冷眼看人间恩怨4 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
红龙创客4 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin4 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
yuanbenshidiaos5 小时前
c++---------数据类型
java·jvm·c++
十年一梦实验室6 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
taoyong0016 小时前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
这是我586 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
Uu_05kkq6 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法