数据结构(排序)

文章目录


一、排序概念

1.1 概念

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

1.2 常见的排序算法

二、实现常见的排序算法

2.1 直接插入排序

复制代码
void InsertSort(int* arr, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;
		int tmp = arr[end + 1];
		while (end >= 0)
		{
			if (arr[end] > tmp)
			{
				arr[end + 1] = arr[end];
				end--;
			}
			else
			{
				break;
			}
			arr[end + 1] = tmp;
		}
	}
}
  • 当插⼊第 i(i>=1) 个元素时,前⾯的 array0,array1,...,arrayi-1 已经排好序,此时⽤ arrayi 的排序码与 arrayi-1,arrayi-2,... 的排序码顺序进⾏⽐较,找到插⼊位置即将 arrayi 插⼊,原来位置上的元素顺序后移:

直接插⼊排序的特性总结

  1. 元素集合越接近有序,直接插⼊排序算法的时间效率越⾼
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)

2.2 希尔排序

复制代码
void ShellSort(int* arr, int n)
{
	int gap = n;
	while (gap > 1)
	{
		int gap = gap / 3 + 1; //保证最后一次的 gap 是 1。
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = arr[end+gap];
			while (end >= 0)
			{
				if (arr[end] > tmp)
				{
					arr[end + gap] = arr[end];
					end-=gap;
				}
				else
				{
					break;
				}
				
			}
			arr[end + gap] = tmp;
		}
	}
}
  • 希尔排序法⼜称缩⼩增量法。希尔排序法的基本思想是:先选定⼀个整数(通常是gap = n/3+1),把待排序⽂件所有记录分成各组,所有的距离相等的记录分在同⼀组内,并对每⼀组内的记录进⾏排序,然后gap=gap/3+1得到下⼀个整数,再将数组分成各组,进⾏插⼊排序,当gap=1时,就相当于直接插⼊排序。
  • 它是在直接插⼊排序算法的基础上进⾏改进⽽来的,综合来说它的效率肯定是要⾼于直接插⼊排序算法的:


希尔排序的特性总结

  1. 希尔排序是对直接插⼊排序的优化。
  2. 当 gap > 1 时都是预排序,⽬的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序 的了,这样就会很快。这样整体⽽⾔,可以达到优化的效果。
希尔排序的时间复杂度计算

希尔排序的时间复杂度估算:
外层循环:
外层循环的时间复杂度可以直接给出为: O (log 2 n ) 或者 O (log 3 n ) ,即 O (log n )
内层循环:

假设⼀共有n个数据,合计gap组,则每组为n/gap个;在每组中,插⼊移动的次数最坏的情况下为
⼀共是gap组,因此:
总计最坏情况下移动总数为:

gap取值有(以除3为例):n/3 n/9 n/27 ...... 2 1
• 当gap为n/3时,移动总数为:
• 当gap为n/9时,移动总数为:
• 最后⼀躺,gap=1即直接插⼊排序,内层循环排序消耗为n

因此,希尔排序在最初和最后的排序的次数都为n,即前⼀阶段排序次数是逐渐上升的状态,当到达某⼀顶点时,排序次数逐渐下降⾄n,⽽该顶点的计算暂时⽆法给出具体的计算过程

  • 希尔排序时间复杂度不好计算,因为 gap 的取值很多,导致很难去计算,因此很多书中给出的希尔排序的时间复杂度都不固定。《数据结构(C语⾔版)》--- 严蔚敏书中给出的时间复杂度为:

2.3直接选择排序

  1. 在元素集合 arrayi--arrayn-1 中选择关键码最⼤(⼩)的数据元素

  2. 若它不是这组元素中的最后⼀个(第⼀个)元素,则将它与这组元素中的最后⼀个(第⼀个)元素交换

  3. 在剩余的 arrayi--arrayn-2(arrayi+1--arrayn-1) 集合中,重复上述步骤,直到集合剩余 1 个元素

    void SlelectSort(int* arr, int n)
    {
    int begin = 0;
    int end = n - 1;
    while (begin < end)
    {
    int min = begin, max = begin;
    for (int i = begin + 1; i <= end; i++)
    {
    if (arr[i] < min)
    {
    min = i;
    }
    if (arr[i] > max)
    {
    max = i;
    }
    }

    复制代码
     	if (max = begin)
     	{
     		max = min;
     	}
     	Swap(&arr[min], &arr[begin]);
     	Swap(&arr[max], &arr[end]);
    
     	begin++;
     	end--;
     }

    }

直接选择排序的特性总结:

  1. 直接选择排序思考⾮常好理解,但是效率不是很好。实际中很少使⽤
  2. 时间复杂度: O(N2 )
  3. 空间复杂度: O(1)

未完待续~~~

相关推荐
留白_9 分钟前
【决策树】泰坦尼克号生存预测
算法·决策树·机器学习
hqzing18 分钟前
鸿蒙 PC 底层开发技术详解(七):二进制自签名算法的实现
算法·华为·harmonyos
AI科技星27 分钟前
超复数全域经济周期场与信息谱场——金融与密码学底层理论重构《0·1·∞三元一体全域超复数统一场论》系列全集(六一字不漏完整合订终版)
人工智能·算法·金融·密码学·拓扑学·乖乖数学·全域数学
AI科技星1 小时前
《01无穷全域信息场论:算子G与宇宙本体高维完备公理大典》
人工智能·python·算法·金融·乖乖数学·全域数学
Tim_101 小时前
【C++】013、空类占多少字节?
算法
Ricky_Theseus1 小时前
并查集:连通性问题
算法
Tairitsu_H2 小时前
[LC优选算法#18] 前缀和 | 除⾃⾝以外数组的乘积 | 和为K的⼦数组 | 和可被K整除的⼦数组
算法·前缀和·哈希算法
凯瑟琳.奥古斯特2 小时前
力扣1008:前序重建BST
开发语言·c++·算法·leetcode·职场和发展
qq_383189622 小时前
07-运放运用电路-程控增益放大器
算法
aqiu1111113 小时前
【算法日记 13】LeetCode 49. 字母异位词分组:哈希表的进阶“降维打击”
算法·leetcode·散列表