【数据结构(二)】用C语言实现冒泡、选择、插入等基本排序算法——用gif图和详细解析让你牢记

目录

六、排序算法     

1. 引子

2.基本排序算法

 2.1  冒泡排序 

2.2选择排序

2.3插入排序

Summery💐 


推荐书籍👌
《大话数据结构》
《数据结构与算法图解》

六、排序算法     

1. 引子

排序在我们遍布的每个角落,还记得高考成绩出来那一天晚上,将自己的分数在一份一线表上查询,名次从上到下逐渐增大;排名就是排序,同样的还有当我们在淘宝上购买时,点击按销量排序一样,等等这些操作计算机是怎样实现的呢?接下来让我将其分为两类,一起来学习排序,。

2.基本排序算法

 2.1  冒泡排序 

相信大家在学习C语言的循环和数组时肯定都写过冒泡排序(BubbleSort)吧,一个简单又复杂的排序

 以升序为例

若数组为9到0,第一层for循环指需要排序的数,第二层for循环是将两两依次比较;这里特别注意i的范围( i < n-1-j ):设想如果将9移动到了最后,那么将8移动到后面的过程中就不需要将8与9比较了;每一次第一层for循环结束就会选一次最大的数排在最后,所以第二次for循环的比较次数会越来越少;

void BubbleSort(int* a, int n)    /* n为数组大小 */
{
	for (int j = 0; j < n - 1; j++)
	{
		for (int i = 0; i < n - 1-j; i++)
		{
			if (a[i] > a[i + 1])
				Swap(&a[i], &a[i + 1]);
		}
	}
}

Swap: ※ 该函数应该在BubbleSort函数之上; ※ 注意解引用符号(*a1)

void Swap(int* a1, int* a2)
{
	int tmp = *a1;
	*a1 = *a2;
	*a2 = tmp;
}

时间复杂度:O(n^2)

2.2选择排序

 所谓选择,就是在每次循环中找到最大和最小的数的下标,在循环的最后将其交换;

文字解析⬇️:

(1)首先定义begin和end分别指向头尾;进入while循环;

(2)直至begin与end指向同一位置;

(3)进入for循环,在本次begin和end指向的范围中,当 i 指向的数大于或小于两头时交换数的位置,最终在begin上为本次循环范围内的最小值,end则为最大值(升序);

(4)最后 begin ++,end --,再次进入while循环,进行下一次的begin与end范围内选择最值。✔️

当然你也可以选择遍历一遍选择最大(最小)然后放在开头(末尾),这里用一次遍历选择最大和最小相当于一个进阶的选择排序;

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

时间复杂度:与冒泡排序同为 O(n^2) ,但是在性能上要略优于冒泡排序。

2.3插入排序

 

斗地主相信大家都玩过吧,拿到牌之后第一时间就是将牌按照自己的习惯一张张地插入到相应位置 ;

下面我就将一部分类比抽牌来解释插入排序的原理(升序)⬇️:

(1)进入for循环(i){   定义end = i ,end指向手中卡牌的最后一张,tmp拷贝抽到的卡牌(a[end + 1]),及end指向的下一个;※ 之所以 i < n - 1 , 当end指向的是倒数第二张牌时,即将排序的是最后一张牌(整个数组的最后一个数),排序玩最后一张牌之后,整个数组就是有序的了;

(2)之后进入while循环   将end指向的数及之前的数,依次与即将插入的数(tmp)比较,若大于tmp,则将该数后移(a[end+1] = a[end])}   若比tmp小则跳出循环,将tmp插入到该数之后;(当end = -1时,及所有数都比tmp大时,tmp插在最开头end == 0的位置) ✔️

}

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) ,但是比冒泡排序和选择排序性能要好;


Summery💐 

•  以上文章已经差不多包含了所有基础的排序算法了,可能与其他文章的代码不同,但是各种排序的思路时大致相同的;

•  后面学习的进阶的排序算法,思路肯定是比基本的冒泡、选择、插入排序要难的,但是算法的时间复杂度少了许多;

•  学习是段漫长的路程,休息一下,接下来我们进入更加复杂的排序算法⬇️

https://blog.csdn.net/Dusong_/article/details/127385058?spm=1001.2014.3001.5502

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dusong_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值