[ 数据结构 -- 手撕排序算法第二篇 ] 冒泡排序

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

手撕排序算法系列之:冒泡排序。

从本篇文章开始,我会介绍并分析常见的几种排序,大致包括插入排序冒泡排序,希尔排序,选择排序,堆排序,快速排序,归并排序等。

大家可以点击此链接阅读其他排序算法:排序算法_大合集(data-structure_Sort)

本篇主要来手撕冒泡排序~~ 

目录

1.常见的排序算法

1.1交换排序

2.冒泡排序的实现

2.1基本思想

2.2单趟冒泡排序

2.2.1思路分析

2.2.2单趟代码实现

3.冒泡排序代码实现

4.冒泡排序测试

5.冒泡排序的时间复杂度

5.1最坏情况 

5.2最好情况

6.冒泡排序的优化写法 

6.1优化思想

6.2优化代码 

6.3优化算法的时间复杂度

6.3.1 最坏情况

6.3.2 最好情况

7.冒泡排序的特性总结

1.常见的排序算法

1.1交换排序

冒泡排序属于一种交换排序,因此我们在了解冒泡排序之前,先了解一下交换排序的基本思想。

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。
交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

[ 数据结构 -- 手撕排序算法第二篇 ] 冒泡排序

2.冒泡排序的实现

2.1基本思想

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

用两个变量指定2个数,如果前一个数比后一个数字大就交换(升序)。

[ 数据结构 -- 手撕排序算法第二篇 ] 冒泡排序

2.2单趟冒泡排序

2.2.1思路分析

单趟下来冒泡排序就会把最大的数字放在最后一位(升序)。

[ 数据结构 -- 手撕排序算法第二篇 ] 冒泡排序

2.2.2单趟代码实现

void Swap(int* pa, int* pb)
{
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}
//单趟
for (int i = 1; i < n ; ++i)
{
	if (a[i - 1] > a[i])
		{
		Swap(&a[i - 1], &a[i]);
		}
}

3.冒泡排序代码实现

在单趟的基础之上,加上一个循环,将单趟套进去即可。需要注意的是,每次循环冒出一个数字,因此单趟循环之后到下一次循环中比较次数就要减一,这里我们使用变量来控制即可

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

4.冒泡排序测试

void Swap(int* pa, int* pb)
{
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}
//冒泡排序 时间复杂度:O(N^2)
void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; ++j)
	{
		//单趟
		for (int i = 1; i < n - j; ++i)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
			}
		}
	}
}
int main()
{
	//冒泡排序
	TestBubbleSort();
	return 0;
}

测试结果:

[ 数据结构 -- 手撕排序算法第二篇 ] 冒泡排序

5.冒泡排序的时间复杂度

5.1最坏情况 

最坏情况:逆序排顺序。假设有n个数,等差数列1+2+3+4+...+n

因此最坏的时间复杂度为O(n^2)。

5.2最好情况

最好情况:有序排有序。对于冒泡排序来说,即使是有序仍然会把每个数进行冒泡。虽然有序,但是冒泡排序不知道呀,仍然按着老套路一个一个比较冒。

因此最好的时间复杂度仍为O(n^2)。

6.冒泡排序的优化写法 

在时间复杂度分析的过程中,我们可以发现,如果序列已经有序了,时间复杂度仍然是O(n^2).因此我们可以对这种情况进行优化。

6.1优化思想

我们定义一个变量,在冒泡的过程中,如果有两个数字进行交换,说明原序列不是有序的,但是如果冒一遍发现,没有数字记性交换,说明该序列是有序的,就没必要继续冒下去了。因此,我们可以定义一个exchange变量,其实赋值为0,如果冒一遍有交换,就让exchange = 1,如果没有交换,不改变exchange的值,我们最后只需要判断exchange的值即可的值序列是否有序。

6.2优化代码 

void Swap(int* pa, int* pb)
{
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}

//冒泡排序 时间复杂度:O(N^2)
//优化:如果前几个已经有序,比较一遍之后后续的无序再进行比较 直接往后走
//实现:定义一个exchange变量,初始化为0;如果交换就说明变化,将exchange变1.
//没变的话就说明有序,就不用往下走 直接break;

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

		if (exchange == 0)
			break;
	}
}

int main()
{
	//冒泡排序
	TestBubbleSort();
	return 0;
}

6.3优化算法的时间复杂度

6.3.1 最坏情况

最坏情况仍是逆序排顺序 时间复杂度O(n^2)

6.3.2 最好情况

最好情况是本身就有序,我们在第一遍冒泡过程过,exchange没有改变,我们就break了。

因此此时的时间复杂度是O(n)。

7.冒泡排序的特性总结

冒泡排序的特性总结:
1. 冒泡排序是一种非常容易理解的排序
2. 时间复杂度: O(N^2)
3. 空间复杂度: O(1)
4. 稳定性:稳定

(本篇完) 文章来源地址https://www.toymoban.com/news/detail-501879.html

到了这里,关于[ 数据结构 -- 手撕排序算法第二篇 ] 冒泡排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • [数据结构 -- 手撕排序算法第七篇] 递归实现归并排序

    目录 1、归并的思想 2、归并排序的思想 2.1 基本思想 2.2 图解分析 3、归并排序递归版本代码实现 3.1 代码解析 3.2 注意事项 3.2.1错误划分:[begin, mid-1],[mid, end] 3.2.2 正确划分:[begin, mid], [mid+1, end] 4、归并排序的测试 5、时间复杂度、空间复杂度分析 5.1 时间复杂度 5.2 空间复杂

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

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

    2024年02月11日
    浏览(46)
  • Mysql第二篇---InnoDB数据存储结构

    索引结构给我们提供了高效的索引方式, 不过索引信息以及数据记录都是保存在文件上的(innodb的ibd文件, MyISAM的MyI和MyD文件), 确切的说是存储在页结构中. 另一方面, 索引是在 存储引擎 中实现的, MySQL服务器上的存储引擎负责对表中数据的读取和写入工作. 不同存储引擎中存放

    2024年02月07日
    浏览(41)
  • [数据结构 -- 手撕排序算法第六篇] 递归实现快速排序(集霍尔版本,挖坑法,前后指针法为一篇的实现方法,很能打)

    目录 1、常见的排序算法 1.1 交换排序基本思想 2、快速排序的实现方法 2.1 基本思想 3 hoare(霍尔)版本 3.1 实现思路 3.2 思路图解 3.3 为什么实现思路的步骤2、3不能交换 3.4 hoare版本代码实现 3.5 hoare版本代码测试 4、挖坑法 4.1 实现思路 4.2 思路图解 4.3 挖坑法代码实现 4.4 挖坑

    2024年02月16日
    浏览(31)
  • 数据结构修炼第二篇:顺序表和链表

    第一章 时间复杂度和空间复杂度 第二章 顺序表,列表 第三章 栈和队列 第四章 二叉树 第五章 排序 作者:🎈乐言🎈 简介:🎈大一学生,目前在致力于c/c++/python,高数的学习,有问题尽管问我,关注后私聊! 持续更新专栏:《c进阶》,《数据结构修炼》 🚀 (优质好文持

    2024年02月02日
    浏览(35)
  • 【数据结构】手撕排序

    🔥 博客主页 : 小羊失眠啦. 🎥 系列专栏 : 《C语言》 《数据结构》 《Linux》 《Cpolar》 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 排序 :所谓排序就是使一串记录,按照其中的某个或某些的大小, 递增或递减 的排列起来的操作。排序算法,就是如何使得记录按照要求

    2024年02月05日
    浏览(34)
  • 【数据结构】手撕排序NO.1----排序初识

    目录  一. 前言 二. 排序的概念及运用         2.1 排序的概念         2.2 排序的运用         2.3 常见的排序算法 三. 冒泡and选择排序         3.1 冒泡排序         3.2 选择排序 四. 各大排序算法的复杂度和稳定性        从本期开始,我们的数据结构将迎来一个新的

    2024年02月16日
    浏览(43)
  • [数据结构 -- 手撕排序第一篇] 插入排序

    目录 1、常见的排序算法 2、插入排序的思路 2.1 基本思想 2.2 直接插入排序 2.2.1 单趟排序的思路 2.2.2 单趟排序代码实现 3、插入排序代码 4、插入排序+打印测试 5、插入排序的时间复杂度 5.1 最坏情况 5.2 最好情况 6、直接插入排序的特性总结   直接插入排序是一种简单的插入

    2024年02月12日
    浏览(32)
  • [数据结构 -- 手撕排序第三篇] 冒泡排序

    目录 1、常见的排序算法 1.1 交换排序基本思想 2、冒泡排序的实现 2.1 基本思想 2.2 单趟排序 2.2.1 单趟排序分析 2.2.2 单趟排序实现代码 3、冒泡排序完整代码实现 3.1 思路分析 3.2 代码实现 4、时间复杂度 5、优化算法 5.1 优化算法思路 5.2 优化算法代码实现 6、冒泡排序的特性总

    2024年02月13日
    浏览(33)
  • 【数据结构】手撕归并排序(含非递归)

    目录 一,归并排序(递归) 1,基本思想  2,思路实现 二,归并排序(非递归) 1,思路实现 2,归并排序的特性总结: 1,基本思想 归并排序 (MERGE-SORT) 是建立在 归并操作 上的一种 有效的排序算法 ,该算法是采用 分治法(Divide and Conquer) 的一个非常典型的应用; 将 已

    2024年02月08日
    浏览(34)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包