冒泡排序
算法思想,一趟比较下来,始终使最大的沉到最下面。这样都比较完了,第一个就是最小的。过于简单,两两比较一轮次比较下来会把较小的数字慢慢浮到上面来。
更新
- 算法图形化网站
- XOR交换
参考:
阮一峰 - 异或运算 XOR 教程
冒泡进阶写法
进阶写法主要关注两数交换方法,那么思考一下两数交换有几种方法呢?
- 引入临时变量
- 两数相加再相减(无额外空间)
a = a + b
b = a - b
a = a - b
void FxxxF(int* nums, int length) {
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - i - 1; j++) {
if (nums[j] > nums[j + 1]) {
nums[j] = nums[j] + nums[j + 1]; //a = a+b a-change sum
nums[j+1] = nums[j] - nums[j + 1]; //b = a -b b equals-a
nums[j ] = nums[j] - nums[j + 1]; //a= a-b
}
}
}
}
- XOR交换(无额外空间)最佳
a = a^b
b = a^b
a = a^b
void FxxxF(int* nums, int length) {
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - i - 1; j++) {
if (nums[j] > nums[j + 1]) {
nums[j] = nums[j] ^ nums[j + 1];
nums[j + 1] = nums[j] ^ nums[j + 1];
nums[j] = nums[j] ^ nums[j + 1];
}
}
}
}
优化后的冒泡排序不需要额外空间!
为什么?最小的会在最后?
因为两两比较,小的放在后位,对于最小的来说,因为最小会一直被交换…交换…交换…交换…然后就到了最后了。
思路
假设有5个数字{54321}。
length-1
第一次排序变成 length-i-1
4321 5 进行了4次比较
第二次排序变成
321 45 进行了3次比较
第三次排序变成
21 345 进行了2次比较
第四次排序变成
1 2345 进行了1次比较
程序
#include "stdafx.h"
#define N 10
int _tmain(int argc, _TCHAR* argv[])
{
int arra[N] = {54,89,64,321,45,1,648,4615,21321,645};
//大循环
for (int i = 0; i < N -1; i++)
{
///小循环
for (int j = 0; j < N - i - 1; j ++)
{
if(arra[j] > arra[j + 1])
{
int temp = arra[j];
arra[j] = arra[j+1];
arra[j + 1] = temp;
}
}
}
for (int i = 0; i < N; i++)
{
printf("%d\n",arra[i]);
}
getchar();
return 0;
}
class Program
{
static void Main(string[] args)
{
int[] arra = new int[5] { 5, 4, 3, 2, 1 };
for (int i = 0; i < arra.Length - 1; i++)
{
for (int j = 0; j < arra.Length - i - 1; j++)
{
if (arra[j] > arra[j + 1])
{
int temp = arra[j];
arra[j] = arra[j + 1];
arra[j + 1] = temp;
}
}
}
foreach (var item in arra)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}
void Bubble(int* arra,int n)
{
int value = sizeof(arra);
for (int i = 0; i < n-1; i++)
{
for (int j = 0; j < n- 1 -i; j++)
{
if (arra[j] > arra[j+1])
{
int temp = arra[j];
arra[j] = arra[j+1];
arra[j+1] = temp;
}
}
}
}
程序描述
结果
###程序分析
什么是循环?循环就是重复做着一件相同的事情。这里做着相同的事情就是比较。外层循环控制比较的轮次,内层循环控制两两比较次数。
####时间复杂度
平方阶O(n^2)
2020年更新
一定要记住动画
从小到大
void swap(int&a, int&b) //这个swap函数非常好 用了引用
{
int temp = a;
a = b;
b = temp;
}
void bubbleSort(vector<int> &numbs) //这么写函数非常简洁
{
for (int end = numbs.size() -1;end != 0;end--){
for (int i = 0;i < end;i++){
if (numbs[i] > numbs[i + 1]){
swap(numbs[i], numbs[i + 1]);
}
}
}
}
排序算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 排序方式 | 稳定性 |
---|---|---|---|---|---|---|
冒泡排序 | O(n2) | O(n) | O(n2) | O(1) | in-place | 稳定 |
空间复杂度:执行一个算法的时候使用的额外的空间。
稳定性:大小相同的位置不同的元素位置颠倒。
算法图形化网站
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
https://visualgo.net/zh/sorting