「数据结构」八大排序1

这篇具有很好参考价值的文章主要介绍了「数据结构」八大排序1。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🎇个人主页:Ice_Sugar_7
🎇所属专栏:初阶数据结构
🎇欢迎点赞收藏加关注哦!

🍉插入排序

插排就是将一个元素插入一个有序序列中合适的位置,分为直接插入排序希尔排序

🍌直接插入排序

流程如下:
①保存待插入的值:假设某一趟中有序序列最后一个元素下标为end,先保存(end+1)位置的元素,保存到临时变量tmp。

②为a[end+1]找到合适的位置:使用while循环,里面比较a[end]和a[end+1]的大小。
若前者<后者,就退出循环
反之,则将a[end]往后挪一位,覆盖掉a[end+1],end减1,然后让tmp继续往前找,直到找到比它小的元素或者end < 0(end<0说明所有元素都比tmp大,那么就应该把tmp放在a[0]),插到该元素后面。

简而言之就是让tmp向前找比它小的元素,找到就插在它的后面;找不到就是插在第一位

③至此,我们排好了一个数据,现在要排列所有元素,只需在外面套上一层for循环
(假设数组有n个元素,注意循环的终止条件是i < n-1,即i最多只能取到n-2,因为是 i 和 i+1 进行比较)

比如:

int a[] = {2,7,1,9,6,5,8};

图解如下:
「数据结构」八大排序1,初阶数据结构,数据结构,排序算法,算法
「数据结构」八大排序1,初阶数据结构,数据结构,排序算法,算法

代码如下:

//n为数组元素个数
void InsertSort(int* a, int n) {
	for (int i = 0; i < n-1; i++) {
		int end = i;  //end为有序序列最后一个元素的下标
		int tmp = a[end + 1];  //tmp保存待插入的数据
		while (end >= 0)
		{
			if (a[end + 1] < a[end]) //待插入的数比end小,那么end就向后移动,给待插入的数据挪出位置
				a[end + 1] = a[end];
			else
				break;
			end--;  //更新end,向前找小 
		}
		//找到小或end == -1
		a[end + 1] = tmp;
	}
}

🥝复杂度及稳定性

时间复杂度:第一趟1次,第二趟2次……由等差数列公式可以推出是O(N^2)
空间复杂度:O(1)
稳定性:稳定


🍌希尔排序

希尔排序是直接插入排序的优化。分两步完成:预排序+直接插入排序
预排序的意义:让大的数更快到后面,小的数更快到前面。使序列趋于有序,降低直接插入排序的成本

🥝预排序

直接插入排序是让相邻的元素进行比较。预排序则是让一个元素和与它相隔几个位置的元素比较
比如:

int a[] = {9,1,2,5,7,4,8,6,3,5};

「数据结构」八大排序1,初阶数据结构,数据结构,排序算法,算法
9、5、8、5可以分为一组;1、7、6也是一组;2、4、3同理
同一组的元素进行比较,排好序。
预排序后得到:
「数据结构」八大排序1,初阶数据结构,数据结构,排序算法,算法

这样就完成了一次预排序。希尔排序中有多次预排序,每次排完后会缩小间隔、重新分组,然后继续预排序。假设最开始的间隔为gap,那么就一直缩小,gap越小,预排序一次后序列就越趋于有序。直到gap为1,此时就是直接插入排序,这一次排好后序列就有序了

gap每次预排序一般是缩小到上一次的一半,或是1/3(注意gap除以3之后需要+1,保证gap不为0)
代码如下:

void ShellSort(int* a, int n) {
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;  //+1确保gap至少为1,最后一次循环gap == 1
		//一次预排序
		for (int i = 0; i < n - gap; i++)  //i+gap最多取到n-1
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > tmp)
					a[end+gap] = a[end];
				else
					break;
				end -= gap;
			}
			a[end + gap] = tmp;
		}
	}
}

🥝复杂度及稳定性

时间复杂度:O(N^1.3)
空间复杂度:O(1)
稳定性:不稳定。因为预排序很容易就把相同的数的相对顺序打乱了


🍉选择排序

排序思路:
●假设序列最左边、右边下标分别为begin、end
●从序列中找出最大、最小值,并分别将它们放到下标为begin、end的地方
●找出第二大和第二小,分别放到begin+1、end-1
●剩下元素也按照这样排列

在“交换位置”这一步有一个很坑的点,如果最小值刚好在end,那就会和最大值交换位置,但是此时我们的mini仍然在end,直接交换a[mini]和a[begin]就会把最大值和begin处的元素交换位置
所以在最大值和a[end]交换之后检查一下,看mini是否在end处。如果是,就将maxi赋值给mini(因为此时maxi指向的就是最小值)

void SelectSort(int* a, int n) {
	int begin = 0;
	int end = n - 1;
	while (begin < end)
	{
		int mini = begin,maxi = begin;
		for (int i = begin + 1; i <= end; i++)
		{
			if (a[maxi] < a[i])
				maxi = i;
			if (a[mini] > a[i])
				mini = i;
		}
		Swap(&a[maxi], &a[end]);
		if (end == mini)  //让mini重新指向最小值
			mini = maxi;
		Swap(&a[mini], &a[begin]);
		++begin;
		--end;
	}
}

🍌复杂度及稳定性

时间复杂度:第一趟走(n-2)次,第二趟走(n-4)次,第 i 趟走(n-2*i)次……由等差数列公式,可以得出时间复杂度为O(N^2)
空间复杂度:O(1)
稳定性:不稳定。比如1 9 9 4 2 1 3 6,第一趟第一个9就会被换到最后面


🍉堆排序

前面的文章有讲过,升序建大堆,降序建小堆
比如排升序,就建大堆,然后让堆顶元素和堆中最后一个元素交换位置,再进行调整

void HeapSort(int* a, int k) {  //a为给定数组
	for (int i = (k - 1 - 1) / 2; i >= 0; i--) {   //调整为一个堆
		AdjustDown(a, k, i);
	}

	for (int i = k - 1; i >= 0; i--) {  //采用删除结点的思想,先交换,再调整
		Swap(a[0], a[i]);
		AdjustDown(a, i, 0);
	}
}

🍌复杂度及稳定性

时间复杂度:如果有n个数据,那么堆的深度就是logn,最坏情况下,有(n-1)个数据需要调整,所以近似是(n-1)logn,又因为logn的量级比nlogn小,可以忽略,所以时间复杂度就是O(N*logN)
(注意:实际比N * logN略小一些)

上面说“近似”是因为并不是每个数据都要调整logn层,但是由于logn一般不大(参考:2的30次方是10亿多一点,此时logn就是30),它的大小一般就是几十这样子,所以相差这一点对于时间复杂度基本没影响

空间复杂度:O(1)
稳定性:不稳定


🍉写在最后

以上就是本篇文章的全部内容,如果你觉得本文对你有所帮助的话,那不妨点个小小的赞哦!(比心)文章来源地址https://www.toymoban.com/news/detail-779570.html

到了这里,关于「数据结构」八大排序1的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构与算法】八大排序

    初看这些概念可能一脸懵,但是没有关系,等下面学完几种排序之后在来看这些概念非常容易理解。 排序:所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在多个具有相同的

    2024年02月01日
    浏览(45)
  • 数据结构之八大排序算法

    排序:所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 下面是常见的排序算法: 直接插入排序是一种简单的插入排序法,其基本思想是: 把待排序的元素按其值的大小逐个插入到一个已经排好序的有序序列中,直到所有的

    2023年04月14日
    浏览(47)
  • 【数据结构】八大排序之简单选择排序算法

    🦄 个人主页 :修修修也 🎏 所属专栏 :数据结构 ⚙️ 操作环境 : Visual Studio 2022 目录 一.简单选择排序简介及思路 二.简单选择排序的代码实现 三.简单选择排序的优化 四.简单选择排序的时间复杂度分析 结语 简单选择排序算法(Simple Selection Sort) 是一种简单直观的 选择排序算

    2024年02月01日
    浏览(62)
  • 【数据结构】 常见的八大排序算法

    排序有 内部排序和外部排序 ,内部排序是数据记录在内存中进行排序,这里八大排序就是内部排序,指直接插入,希尔,选择,堆排,冒泡,快排,归并,计数。 下面让我们来共同学习这八大排序吧!🤗🤗🤗 什么是外部排序: 外排序是数据量较大,内存放不下,数据放到外

    2024年02月12日
    浏览(58)
  • 【数据结构】--八大排序算法【完整版】

    本文主要讲解代码及代码思路,涵盖八大排序的全面知识点 ———————————————— 目录 一、直接插入排序 二、希尔排序(直接插入排序的改良版) 三、选择排序(直接选择排序) 四、堆排序 五、冒泡排序 六、快速排序 1、 左右指针法 2、挖坑法: 3、前后指针

    2024年02月16日
    浏览(30)
  • 第五章 数据结构与算法——八大排序

    目录 一、排序的概念及其运用 二、八大排序的原理及其实现(升序为例) (一)、直接插入排序 (二)、希尔排序(也叫缩小增量排序)(重要) 1.原理: 2.该排序一般分为两个步骤: 3.预排序过程: 4.预排序的意义(升序为例): 5.希尔排序的特点: 6.希尔排序代码实现

    2024年02月19日
    浏览(33)
  • 【数据结构】八大排序算法(内含思维导图和画图分析)

    作者主页: paper jie_博客 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于《JAVA数据结构》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将javaSE基础知识一网打尽,希望可以帮到读者们哦。 其他专栏:

    2024年02月08日
    浏览(45)
  • 手把手教你 ,带你彻底掌握八大排序算法【数据结构】

    直接插入排序是一种简单的插入排序法,其基本思想:是把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 可以理解为一遍摸扑克牌,一边进行排序 在待排序的元素中,假设前面n-1(其中n=2)个数

    2024年02月02日
    浏览(35)
  • 【数据结构与算法】万字剖析八大排序(直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序)

    初窥直接插入排序我们先来看一张动图: 由动图我们可以分析出直接插入排序是从 第二个数据开始遍历 ,与 前面的数据进行比较 如果小于 则让前面的数据向前移动 自己接着向前面的数据比较 直到比较到 大于等于自己的 数据或者 没有数据能进行比较 时停止 插入当前的位

    2023年04月13日
    浏览(42)
  • 【数据结构与算法篇】手撕八大排序算法之快排的非递归实现及递归版本优化(三路划分)

    ​👻内容专栏: 《数据结构与算法篇》 🐨本文概括: 利用数据结构栈(Stack)来模拟递归,实现快排的非递归版本;递归版本测试OJ题时,有大量重复元素样例不能通过,导致性能下降,优化快速排序通过将数组划分为三个区域,可以更有效地处理重复元素。 🐼本文作者:

    2024年02月11日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包