【排序算法】冒泡排序 【包含XOR进阶写法】

本文介绍了冒泡排序的基本原理,通过图形化和代码示例详细讲解了冒泡排序的过程,包括传统方法、XOR交换优化版,并探讨了空间复杂度为O(1)的特性。重点分析了算法的时间复杂度和稳定性,以及不同写法的对比和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

冒泡排序

算法思想,一趟比较下来,始终使最大的沉到最下面。这样都比较完了,第一个就是最小的。过于简单,两两比较一轮次比较下来会把较小的数字慢慢浮到上面来。

更新
  1. 算法图形化网站
  2. XOR交换
    在这里插入图片描述
    参考:
    阮一峰 - 异或运算 XOR 教程

冒泡进阶写法

进阶写法主要关注两数交换方法,那么思考一下两数交换有几种方法呢?

  1. 引入临时变量
  2. 两数相加再相减(无额外空间)
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  
			}
		}
	}
}
  1. 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];
			}
		}
	}
}

优化后的冒泡排序不需要额外空间!

为什么?最小的会在最后?

因为两两比较,小的放在后位,对于最小的来说,因为最小会一直被交换…交换…交换…交换…然后就到了最后了。

image

思路

假设有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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值