【数据结构】八大排序(一)

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

😛作者:日出等日落

📘 专栏:数据结构

        珍惜自己的时间,利用好每一份每一秒。做事不放过没一个细节,小心谨慎,细致,能够做到这些,还有什么是不可能的呢?

【数据结构】八大排序(一)

目录

​编辑

✔排序的概念:

✔排序的应用:

✔常见的排序算法:

✔常见排序算法的实现:

✔插入排序:

✔基本思想:

✔直接插入排序: 

✔思路:

✔代码实现:

✔希尔排序:

✔基本思想:

✔思路:

✔代码实现: 

✔选择排序:

✔基本思想:

✔直接选择排序: 

✔思路:

✔代码实现:

✔堆排序:

✔基本思想:

✔代码实现:

✔冒泡排序:

✔代码实现:


 

 

✔排序的概念:

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

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

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

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

✔排序的应用:

在生活中我们也经常用到排序:

比如淘宝、京东等购物的销量排序、价格排序等等 

如:

【数据结构】八大排序(一)

✔常见的排序算法:

【数据结构】八大排序(一)

 

✔常见排序算法的实现:

✔插入排序:

✔基本思想:

直接插入排序是一种简单的插入排序法,其基本思想是:

把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为 止,得到一个新的有序序列 。

实际中我们玩扑克牌时,就用了插入排序的思想

【数据结构】八大排序(一) 

✔直接插入排序: 

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



动图演示:【数据结构】八大排序(一)

 

✔思路:

用变量end=i,利用tmp记录下end位置的下一个位置a[end+1]的值,

如果a[end]>tmp就将end所对应的值往后移一个;a]end+1]=a[end],然后end--。最后将tmp的值赋给end+1的位置(注意此时tmp虽然是end+1下标,但是end是已经--后的值)。

当数组有n个数时,下标最大值为n-1

当end=n-1时,end+1=n(此时造成了越界)

✔代码实现:

//插入排序
void InsertSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;
		int tmp = a[end + 1];
		while (end >= 0)
		{
			if (a[end] > tmp)
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

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

直接插入排序的特性总结:

1. 元素集合越接近有序,直接插入排序算法的时间效率越高

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

3. 空间复杂度:O(1),它是一种稳定的排序算法

4. 稳定性:稳定 文章来源地址https://www.toymoban.com/news/detail-438886.html

 

普通插入排序的时间复杂度最坏情况下为O(N^2),此时待排序列为逆序,或者说接近逆序。

普通插入排序的时间复杂度最好情况下为O(N),此时待排序列为升序,或者说接近升序

✔希尔排序:

✔基本思想:

希尔排序法又称缩小增量法。

希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成gap个 组,所有距离为gap的记录分在同一组内,并对每一组内的记录进行排序。然后重复上述分组和排序的工 作。当到达=1时,所有记录在统一组内排好序。

【数据结构】八大排序(一)

 

动图演示:

【数据结构】八大排序(一)

✔思路:

单趟排序:

当a[end]>a[end+gap]时,将end的值赋给end+gap后再end-=gap,

在end<0时退出循环

当有n个数时,比较的是相距gap距离的两个数比较,因此循环次数要小于n-gap次

gap=n每次取半直到最终取到gap=1时,每次取半都是一次一次单趟排序

✔代码实现: 

//希尔排序
void ShellSort(int* a, int n)
{
	//gap>1 预排序
	//gap == 1 相当于直接插入排序
	int gap = n;
	while (gap > 1)
	{
		//gap = gap / 2;
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > tmp)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
		//一趟排序后打印一次
		//PrintArray(a, n);
	}
}

时间复杂度:O ( NlogN )   

空间复杂度:O ( 1 )

平均时间复杂度:O ( N^ 1.3 ) 

希尔排序的特性总结:

1. 希尔排序是对直接插入排序的优化。

2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就 会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

【数据结构】八大排序(一)

3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的 希尔排序的时间复杂度都不固定 

4. 稳定性:不稳定

 

✔选择排序:

✔基本思想:

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

直接选择排序: 

在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素

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

在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

动图演示:

【数据结构】八大排序(一)

 

✔思路:

思路:

设两个下标begin和end,begin初始化为0,end初始化为n-1

设置最大值maxi和最小值mini的下标让他们指向begin

当a[i]的值比a[begin]小,更新min的值,当a[i]的值比a[begin]大,更新max的值

循环走完后确认了最小值的下标,将a[begin]和a[min]进行交换,以及a[end]和a[max交换]

当最大值为数组的第一个时,max=min

这就完成了一趟排序

✔代码实现:

//选择排序
void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	
	while (begin < end)
	{
		int mini = begin;
		int maxi = begin;
		for (int i = begin + 1; i <= end; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;
			}
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
			
		}
		Swap(&a[begin], &a[mini]);
		if (maxi == begin)
		{
			maxi = mini;
		}
		Swap(&a[end], &a[maxi]);
		begin++;
		end--;
	}
}

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

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

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

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

4. 稳定性:不稳定

 

✔堆排序:

✔基本思想:

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是 通过堆来进行选择数据。需要注意的是排升序要建大堆排降序建小堆

详细堆排序请看:http://t.csdn.cn/bqJFk 

✔代码实现:

//交换函数
void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//向下调整
void AdjustDown(int* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && a[child + 1] > a[child])
		{
			child = child + 1;
		}
		//child 大于 parent 就交换
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

//堆排序
void HeapSort(int* a, int n)
{
	//这里采用向下调整O(n)
	//建堆算法
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDown(a, n, i);
	}
	int end = n - 1;

	//N*O(m=n)
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		--end;
	}
}

堆排序的特性总结:

1. 堆排序使用堆来选数,效率就高了很多。

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

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

4. 稳定性:不稳定

 

✔冒泡排序:

冒泡排序是我们最熟悉的排序,其思想也最为简单,再次不过多介绍,直接演示

动图演示:

【数据结构】八大排序(一)

✔代码实现:

//冒泡排序
void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n - 1  ; j++)
	{
		for (int i = 0; i < n - j - 1 ; i++)
		{
			if (a[i] > a[i + 1])
			{
				Swap(&a[i], &a[i + 1]);
			}
		}
	}
}

 冒泡排序的特性总结:

1. 冒泡排序是一种非常容易理解的排序

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

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

4. 稳定性:稳定 

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

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

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

相关文章

  • 「数据结构」八大排序1

    🎇 个人主页 :Ice_Sugar_7 🎇 所属专栏 :初阶数据结构 🎇 欢迎点赞收藏加关注哦! 插排就是将一个元素插入一个有序序列中合适的位置,分为 直接插入排序 和 希尔排序 流程如下: ①保存待插入的值:假设某一趟中有序序列最后一个元素下标为end,先 保存(end+1)位置的

    2024年02月03日
    浏览(26)
  • 数据结构--八大排序

    插入排序的思想跟摸牌很相似,从我们摸到第二张牌的开始,依次将摸到到牌依次有序的插入到手中,最后手牌变成了有序。 有了大致的思路,接下来就要细分插入排序的细节。 首先考虑某一趟的插入排序。为什么先考虑某一趟呢?因为当需要解决的问题比较复杂时先将问

    2024年02月02日
    浏览(30)
  • 【数据结构】八大排序(二)

    😛作者:日出等日落 📘 专栏:数据结构 在最黑暗的那段人生,是我自己把自己拉出深渊。没有那个人,我就做那个人。                                                                                                                                     

    2024年02月03日
    浏览(23)
  • 【数据结构】八大排序 (三)

    目录 前言: 快速排序 快速排序非递归实现 快速排序特性总结 归并排序 归并排序的代码实现 归并排序的特性总结 计数排序 计数排序的代码实现 计数排序的特性总结 前文快速排序采用了递归实现,而递归会开辟函数栈帧,递归的深度越深,占用栈区的空间就越大, 栈区的

    2024年02月01日
    浏览(35)
  • 【数据结构】八大排序详解

    🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🐌 个人主页:蜗牛牛啊 🔥 系列专栏:🛹数据结构、🛴C++ 📕 学习格言:博观而约取,厚积而薄发 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与

    2024年02月13日
    浏览(26)
  • 【数据结构】八大排序(一)

    目录 前言: 直接插入排序 直接插入排序代码实现 直接插入排序特性总结 希尔排序 希尔排序代码实现 希尔排序特性总结 直接选择排序 直接选择排序代码实现 直接选择排序特性总结 堆排序 堆的向下调整算法 建堆 堆排序代码实现 堆排序特性总结 排序即使得一串记录,按照

    2024年02月03日
    浏览(30)
  • 【数据结构】八大排序算法

    目录 一、直接插入排序 二、希尔排序 三、选择排序  3.1、简单选择排序  3.2、快速选择排序(Top K问题) 四、堆排序 五、冒泡排序 六、快速排序   1、递归版本      1.1 hoare 法      1.2 挖坑法      1.3 前后指针法   2、非递归版本   3、快速排序的优化      3.1 三数取中

    2024年02月09日
    浏览(57)
  • 【数据结构与算法】八大排序

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

    2024年02月01日
    浏览(45)
  • c++【数据结构】 八大排序

    在计算机科学中,排序算法是最重要的算法之一。排序算法可以将一组无序的数据按照一定的规则重新排列,使其变为有序的数据集合。排序算法的应用十分广泛,它们在计算机科学、数据结构、数据库、人工智能、机器学习等领域都扮演着重要的角色。 本文将介绍C++/C语言

    2024年02月10日
    浏览(32)
  • 【数据结构】图解八大排序(下)

    在上一篇文章中,我们已经学习了五种排序算法,还没看过的小伙伴可以去看一下:传送门 今天要讲的是八大排序中剩下的三种,这三种排序算法用的是非常多的,需要好好掌握。 下面介绍的排序算法均以排升序为例。 快排的思想 是分治,就是选定一个基准值,使这个值的

    2024年02月17日
    浏览(33)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包