活动地址:CSDN21天学习挑战赛
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
想系统/深入学习某技术知识点…
一个人摸索学习很难坚持,想组团高效学习…
想写博客但无从下手,急需写作干货注入能量…
热爱写作,愿意让自己成为更好的人…
正文
梗:
-
冒泡排序,作为最基本的排序算法,由于原理像冒泡一样,所以取名为冒泡排序;
我们知道,水泡在上升时,总是密度最小的最先上去,假如一个水层只能容纳一个水泡,那么水泡由上到下的排序就是密度逐渐增大的排序。类似的,我们可以实现一个相似的排序算法,冒泡排序。 -
At first,我们先look一张我从某文章*的表格,来了解一下这几大算法
-
图都看了,那我也不得不提一嘴,图里面的东西了
-
算法效率
在一个算法设计完成后,还需要对算法的执行情况做一个评估。一个好的算法,可以大幅度的节省运行的资源消耗和时间。在进行评估时不需要太具体,毕竟数据量是不确定的,通常是以数据量为基准来确定一个量级,通常会使用到时间复杂度和空间复杂度这两个概念。 -
时间复杂度
通常把算法中的基本操作重复执行的频度称为算法的时间复杂度。算法中的基本操作一般是指算法中最深层循环内的语句(赋值、判断、四则运算等基础操作)。我们可以把时问频度记为T(n),它与算法中语句的执行次数成正比。其中的n被称为问题的规模,大多数情况下为输入的数据量。对于每一段代码,都可以转化为常数或与n相关的函数表达式,记做f(n)。如果我们把每一段代码的花费的时间加起来就能够得到一个刻画时间复杂度的表达式,在合并后保留量级最大的部分即可确定时间复杂度,记做O(f(n)),其中的O就是代表数量级。
常见的时间复杂度有(由低到高): O(1)、O(log2 n)、O(n)、O(n log2n)、O(n2)、o(n3)、O(2")、O(nl)。 -
空间复杂度
程序从开始执行到结束所需要的内存容量,也就是整个过程中最大需要占用多少的空间。为了评估算法本身,输入数据所占用的空间不会考虑,通常更关注算法运行时需要额外定义多少临时变量或多少存储结构。如:如果需要借助一个临时变量来进行两个元素的交换,则空间复杂度为O(1).
-
时间复杂度与空间复杂度的分类
时间复杂度
-
最坏的情况
最坏的情况莫过于,完整的遍历了整个集合,也没有找到需要找的的元素,循环执行次数与n相关,所以时间复杂度为O(n). -
最好的情况
第一次循环便找到了元素,则时间复杂度为常数级O(1); -
平常的情况
综合两种情况,顺序查找的时间复杂度为O(n),属于查找较慢的算法。
空间复杂度
算法不会改变原有的元素集合,只需要一个额外的变量控制索引变化,所以空间复杂度为常数级:O(1)。
冒泡排序
如上图我从某博主的博客*的图,便可以清楚的看出冒泡排序的特点。
冒泡排序,可以从左往右,也可以从右往左,全看心情,比较两个相邻的元素。比大比小,也是全部看心情。
冒泡排序思路
- 比较相邻的两个元素,如过前面的元素比后面的大,就将它们两个交换位置。
- 对所有元素做完上面的操作,从第一对再到最后一对,就这样,最后的元素是最大的数
- 对于所有的元素再进行第一步的操作,出去最后一个
代码:
void BubbleSort(vector<int>& v) {
int len = v.size();
for (int i = 0; i < len - 1; ++i)
for (int j = 0; j < len - 1 - i; ++j)
if (v[j] > v[j + 1])
swap(v[j], v[j + 1]);
}
如上图所示,但是这样我么就忽略了一个问题,如果这个数组一开始就是有序的,根本不需要排序,但是程序并不会自行判断,直接无脑带入循环进去判断,
所以我们应该添加一个判断一个数组是否有序
void BubbleSort_orderly(vector<int>& v) {
int len = v.size();
bool orderly = false;
for (int i = 0; i < len - 1 && !orderly; ++i) {
orderly = true;
for (int j = 0; j < len - 1 - i; ++j) {
if (v[j] > v[j + 1]) { // 从小到大
orderly = false; // 发生交换则仍非有序
swap(v[j], v[j + 1]);
}
}
}
}
测试数据(无图无真相)
首先展示一下源代码:
为了怕你们手敲很难,我特意贴出源代码
#include <vector>
#include <iostream>
using namespace std;
vector <int> v{ 2,3,1,4,5,6,7,8,10,23,20 };
void BubbleSorderly(vector<int>& v) {
//打印交换前的v向量
cout << "排序前 " << endl;
for (int i = 0; i <= v.size() - 1; i++){
cout << v.at(i) << " ";
}
int len = v.size();
bool orderly = false;
for (int i = 0; i < len - 1 && !orderly; ++i) {
orderly = true;
for (int j = 0; j < len - 1 - i; ++j) {
if (v[j] > v[j + 1]) { // 从小到大
orderly = false; // 发生交换则仍非有序
swap(v[j], v[j + 1]);
}
}
}
cout << "排序后" << endl;
//打印整个vector
for (int i = 0; i <= v.size() - 1; i++){
cout << v.at(i) <<" ";
}
}
int main()
{
BubbleSorderly(v);
return 0;
}
这么简单的源代码就不讲了,你们不会要求我讲吧?
直接贴上测试图;无图无真相
这里我们可以看见排序非常的成功,速度也是非常的quickly。
看到这里了,就把赞留下吧。