从理论到代码:彻底掌握冒泡、选择、插入排序

365bet线上足球 admin 2025-07-13 02:54:58

目录

一、冒泡法排序

1、基本逻辑

2、时间复杂度

3、稳定性

4、C语言实现冒泡法排序

二、选择排序

1、基本逻辑

2、 时间复杂度

3、 稳定性

4、C语言实现选择排序

三、插入排序

1、基本逻辑

2、时间复杂度

3、稳定性

4、C语言实现插入排序

嗨,感谢你打开这篇文章!👋 如果阅读中发现任何笔误或表述不清的地方,欢迎随时留言告诉我~你的视角会让内容变得更完善!

一、冒泡法排序

1、基本逻辑

(1)冒泡排序(Bubble Sort)是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

(2)首先从数组的第一个元素开始,对数组中相邻的两个元素进行比较,如果位于数组左端的元素大于数组右端的元素,则交换这两个元素在数组中的位置(如arr[0] > arr[1],则交换arr[0]与arr[1]的值,然后在比较arr[1]与arr[2]的值,大于则交换),继续这个操作一直到数组的最后一个元素。这样操作后数组最右端的元素即为该数组中所有元素的最大值。接着对该数组除最右端的n-1个元素进行同样的操作,再接着对剩下的n-2个元素做同样的操作,直到整个数组有序排列。

此处以升序为例,第一趟排序:3和6比较,不交换(数组为[3,4]),6和4比较,6大于4,交换(数组为[3,4,6],如果等于也是不交换的),6和2比较大于,交换(数组为[3,4,2,6]),6和11比较,不交换(数组为[3,4,2,6,11),11和10比较大于,交换(数组为[3,4,2,6,10,11]),11和5比较,不交换,最终数组为[3,4,2,6,10,5,11],通过前面的比较,将最大值11放在了数组最右端,他左端的元素都比它小。第二趟排序,重复第一趟排序操作,求出10为除11以外剩余元素里面最大的数,放在倒数第二个,重复以上操作就可以将这个数列进行升序操作。若要做降序操作,思路一样,将最小值放在最右端即可。

动图:

2、时间复杂度

冒泡法排序的时间复杂度为O(n^2)。

3、稳定性

冒泡法排序是一种稳定的算法

算法稳定性:假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!

举个例子,有一个数组初始为[2,3,2,4](为了区别两个2不同,用两个不同的颜色),如果进行排序后,数组为[2,2,3,4](升序),在排序前,黑色2在红色2前面,排序后依旧还在前面,则说明这个排序是一个稳定的算法,如果进行排序后,数组为[2,2,3,4],红色2到了黑色2前面,则说明这个排序不是一个稳定的算法。

4、C语言实现冒泡法排序

/*

* @breif 对一个数组进行冒泡法升序排序

* @param arr 接受需要排序的数组的首地址

* @param len 数组的长度

* @return 成功返回TRUE 失败返回 FALSE

**/

int bubble_sort(int* arr, int len)

{

if (NULL == arr)//判断arr是否为NULL

return FALSE;

//外遍历(趟数),如果数组长度为len,则最后一个元素的下标为len-1,遍历len-1次

for (int i = 0;i < len - 1;i++)

{

//内遍历(每次躺数中比较的次数),随着外遍历的增加,内遍历的次数依次减少,遍历len-1-i次

for (int j = 0;j < len - 1 - i;j++)

{

if (arr[j] > arr[j + 1])//如果连续的两个元素,大于则交换,小于等于不动

{

arr[j] = arr[j] ^ arr[j + 1];//用异或来交换两个值

arr[j + 1] = arr[j] ^ arr[j + 1];

arr[j] = arr[j] ^ arr[j + 1];

}

}

}

return TRUE;

}

二、选择排序

1、基本逻辑

(1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

(2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

(3)重复第二步,直到所有元素均排序完毕。

假设数组为[1,3,6,5,4,2](以升序为例),首先找到最小的元素1,1就为排序序列的起始位置[1],剩余未排序的元素为[3,6,5,4,2],在从剩未排序的元素找最小的元素为2,放入已排序序列的末尾[1,2],未排序的元素为[3,6,5,4],重复以上操作,即可得出升序排序序列[1,2,3,4,5,6]。

动图:

2、 时间复杂度

选择排序的时间复杂度为O(n^2)。

3、 稳定性

选择排序是一种不稳定的算法

4、C语言实现选择排序

/*

* @breif 对一个数组进行选择升序排序

* @param arr 接受需要排序的数组的首地址

* @param len 数组的长度

* @return 成功返回TRUE 失败返回 FALSE

**/

int select_sort(int* arr, int len)

{

if (NULL == arr)

return FALSE;

//外遍历(趟数),如果数组长度为len,则最后一个元素的下标为len-1,遍历len-1次

for (int i = 0;i < len - 1;i++)

{

//保存最小值,先初始化第一个元素为最小值

int min = arr[i];

//内遍历(每次躺数中比较的次数),随着外遍历的增加,内遍历的次数依次减少,遍历len-1-i次

for (int j = i;j < len - 1 - i;j++)

{

if (min > arr[j])//如果遍历到的元素小于最小值,则进行交换

{

min = min ^ arr[j];//用异或来交换两个值

arr[j] = min ^ arr[j];

min = min ^ arr[j ];

}

}

}

return TRUE;

}

三、插入排序

插入排序的基本思想就是将无序序列插入到有序序列中。插入排序的的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

1、基本逻辑

(1)将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

(2)从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

图示:

第一轮: 从第二位置的 6 开始比较,比前面 7 小,交换位置。

第二轮: 第三位置的 9 比前一位置的 7 大,无需交换位置。

第三轮: 第四位置的 3 比前一位置的 9 小交换位置,依次往前比较。

第四轮: 第五位置的 1 比前一位置的 9 小,交换位置,再依次往前比较。

就这样依次比较到最后一个元素。

动图:

2、时间复杂度

插入排序的时间复杂度为O(n^2)。

3、稳定性

插入排序是稳定的排序算法

4、C语言实现插入排序

/*

* @breif 对一个数组进行插入升序排序

* @param arr 接受需要排序的数组的首地址

* @param len 数组的长度

* @return 成功返回TRUE 失败返回 FALSE

**/

int insert_sort(int* arr, int len)

{

if (NULL == arr)

return FALSE;

for (int i = 1;i <= len - 1;i++)

{

//将a[i]的值赋给key,拿key和前面升序序列中的元素进行比较(从右往左)

int key = arr[i];

int j = i - 1;

//如果key比遍历到的元素要小则交换位置,直到遍历到一个<=key的元素,或者前面有序序列遍历完毕,插入arr[i]结束

while (j > 0 && key < arr[j])

{

arr[j + 1] = arr[j];

j--;

}

arr[j + 1] = key;

}

return TRUE;

}

相关文章

库尔勒| 山水梨城,大美新疆

新增17个新职业和42个新工种,这里面藏着哪些机会?

天涯是什么意思

Apple 播客网页版

你思考过你的思考吗?

在excel中怎么随机选人

斗鱼贵族系统是什么?怎么玩?

不同类型防火墙的优缺点分析:从硬件到软件,如何选择最适合你的防火墙?

电动车充电一般多长时间充满?电动车充一次电要多久