排序之冒泡排序(C# C++)

目录

[1 冒泡排序的原理](#1 冒泡排序的原理)

[2 算法步骤](#2 算法步骤)

[3 代码示例](#3 代码示例)

3-1 C#代码示例

[3-2 C++代码示例](#3-2 C++代码示例)


1 冒泡排序的原理

冒泡排序(Bubble Sort)是一种简单的排序算法,它的基本思想是通过多次遍历待排序的数组,比较相邻元素的大小,并根据需要交换它们的位置,直到整个数组有序。

2 算法步骤

  1. 比较相邻元素:从数组的第一个元素开始,依次比较相邻的两个元素。如果前一个元素大于后一个元素,则交换它们的位置。
  2. 重复比较:对数组中的每一对相邻元素都进行上述比较和交换操作,直到数组的最后一个元素。这样,经过一轮比较后,最大的元素就会 "冒泡" 到数组的末尾。
  3. 缩小范围:重复上述步骤,但每次比较的范围逐渐缩小,因为每一轮排序都会将当前未排序部分的最大元素移动到末尾,所以下一轮排序时可以不再考虑这些已经排好序的元素。
  4. 终止条件:当某一轮排序中没有发生元素交换时,说明数组已经有序,排序过程可以提前终止。

3 代码示例

3-1 C#代码示例

根据算法步骤书写以下代码:(优化前)

cs 复制代码
using System;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static int[] BubbleSort(int[] arr)
        {
            if (arr == null || arr.Length < 2) return arr;
            for (int e = arr.Length - 1; e > 0; e--)
                for (int i = 0; i < e; i++)
                    if (arr[i] > arr[i + 1])
                        Swap(arr,i,i+1);
            return arr;
        }
        private static void Swap(int[] arr, int i, int j)
        {
            arr[i] ^= arr[j];
            arr[j] = arr[i] ^ arr[j];
            arr[i] ^= arr[j];
        }
        public static void Main(string[] args)
        {
            int[] arr = { 2, 5, 7, 9, 3, 1, 4, 6, 8 };
            arr = BubbleSort(arr);
            foreach (var value in arr)
            {
                Console.WriteLine(value);
            }
        }
    }
}

仔细观察,可以发现该代码可以进行优化:

使用了异或运算来交换数组中两个元素的位置。异或运算的优点是不需要额外的临时变量,但存在一个问题:当ij指向数组的同一个位置时,异或交换会将该位置的元素置为 0。例如:

cs 复制代码
int a = 5;
a ^= a;  // a 变为 0

针对这个问题,我们对Swap方法添加对ij是否相等的检查。

原始代码在每一轮排序中都会进行完整的比较和交换操作,即使数组已经有序也会继续执行,这会浪费一些不必要的计算资源。针对这一问题,我们可以对其添加一个布尔变量swapped,用于记录每一轮排序中是否发生了元素交换。

优化后代码:

cs 复制代码
using System;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static int[] BubbleSort(int[] arr)
        {
            if (arr == null || arr.Length < 2) return arr;
            for (int e = arr.Length - 1; e > 0; e--)
            {
                bool swapped = false;
                for (int i = 0; i < e; i++)
                    if (arr[i] > arr[i + 1])
                    {
                        Swap(arr, i, i + 1);
                        swapped = true;
                    }
                if(!swapped)break;
            }
            return arr;
        }
        private static void Swap(int[] arr, int i, int j)
        {
            if (i!= j)
            {
                arr[i] ^= arr[j];
                arr[j] = arr[i] ^ arr[j];
                arr[i] ^= arr[j];
            }
        }
        public static void Main(string[] args)
        {
            int[] arr = { 2, 5, 7, 9, 3, 1, 4, 6, 8 };
            arr = BubbleSort(arr);
            foreach (var value in arr)
                Console.WriteLine(value);
        }
    }
}

运行测试:

3-2 C++代码示例
cpp 复制代码
#include <iostream>
#include <vector>

// 交换数组中两个元素的位置
void Swap(std::vector<int>& arr, int i, int j) {
    if (i != j) {
        arr[i] ^= arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] ^= arr[j];
    }
}

// 冒泡排序函数
std::vector<int> BubbleSort(std::vector<int> arr) {
    if (arr.size() < 2) return arr;
    for (int e = arr.size() - 1; e > 0; e--) {
        bool swapped = false;
        for (int i = 0; i < e; i++) {
            if (arr[i] > arr[i + 1]) {
                Swap(arr, i, i + 1);
                swapped = true;
            }
        }
        if (!swapped) break;
    }
    return arr;
}

int main() {
    std::vector<int> arr = { 2, 5, 7, 9, 3, 1, 4, 6, 8 };
    arr = BubbleSort(arr);
    for (int value : arr) {
        std::cout << value << std::endl;
    }
    return 0;
}

测试运行:

相关推荐
じ☆ve 清风°1 小时前
JavaScript 原型与原型链:深入理解 __proto__ 和 prototype 的由来与关系
开发语言·javascript·原型模式
_r0bin_5 小时前
前端面试准备-7
开发语言·前端·javascript·fetch·跨域·class
zhang98800005 小时前
JavaScript 核心原理深度解析-不停留于表面的VUE等的使用!
开发语言·javascript·vue.js
Fanxt_Ja7 小时前
【JVM】三色标记法原理
java·开发语言·jvm·算法
蓝婷儿7 小时前
6个月Python学习计划 Day 15 - 函数式编程、高阶函数、生成器/迭代器
开发语言·python·学习
love530love7 小时前
【笔记】在 MSYS2(MINGW64)中正确安装 Rust
运维·开发语言·人工智能·windows·笔记·python·rust
南郁8 小时前
007-nlohmann/json 项目应用-C++开源库108杰
c++·开源·json·nlohmann·现代c++·d2school·108杰
slandarer8 小时前
MATLAB | 绘图复刻(十九)| 轻松拿捏 Nature Communications 绘图
开发语言·matlab
狐凄8 小时前
Python实例题:Python计算二元二次方程组
开发语言·python
roman_日积跬步-终至千里8 小时前
【Go语言基础【3】】变量、常量、值类型与引用类型
开发语言·算法·golang