冒泡排序及其改进算法:深入理解与实践

冒泡排序及其改进算法:深入理解与实践

冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素为止。

算法步骤

  1. 比较相邻的元素。如果第一个比第二个大(升序排列),就交换它们两个。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

伪代码

复制代码
procedure bubbleSort( A : list of sortable items )
    n = length(A)
    repeat
        swapped = false
        for i = 1 to n-1 inclusive do
            if A[i-1] > A[i] then
                swap( A[i-1], A[i] )
                swapped = true
            end if
        end for
    until not swapped
end procedure

冒泡排序的改进

1. 优化的冒泡排序

在标准冒泡排序中,每次遍历至少会将一个元素放到它应该在的位置。因此,我们可以在每次遍历后,减少比较的元素数量,因为最后的元素已经是排序好的了。

2. 鸡尾酒排序(Cocktail Sort)

鸡尾酒排序,也称为双向冒泡排序,是冒泡排序的一种变体。它在每一轮排序中交替进行正向和反向的遍历,这样可以同时将最大的元素移动到数列的末端,以及最小的元素移动到数列的开头。

实现冒泡排序

以下是一个使用Python实现的冒泡排序示例:

python 复制代码
def bubble_sort(arr):
    n = len(arr)
    # 优化的冒泡排序
    for i in range(n):
        # 初始化交换标志
        swapped = False
        # 最后i个元素已经是排序好的了,不需要再比较
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                swapped = True
        # 如果没有发生交换,说明数组已经排序好了
        if not swapped:
            break
    return arr

# 鸡尾酒排序的实现
def cocktail_sort(arr):
    n = len(arr)
    swapped = True
    start = 0
    end = n - 1
    while swapped:
        swapped = False
        # 正向遍历
        for i in range(start, end):
            if arr[i] > arr[i + 1]:
                arr[i], arr[i + 1] = arr[i + 1], arr[i]
                swapped = True
        # 如果没有交换,说明数组已经排序好了
        if not swapped:
            break
        # 更新结束位置
        end -= 1
        # 反向遍历
        for i in range(end - 1, start - 1, -1):
            if arr[i] > arr[i + 1]:
                arr[i], arr[i + 1] = arr[i + 1], arr[i]
                swapped = True
        # 更新开始位置
        start += 1
    return arr

# 示例
arr = [64, 34, 25, 12, 22, 11, 90]
print("Original array:", arr)
print("Sorted array using Bubble Sort:", bubble_sort(arr.copy()))
print("Sorted array using Cocktail Sort:", cocktail_sort(arr.copy()))

两数交换

先加后减

bash 复制代码
int a = 1,b = 2;
a = a + b;
b = a - b;
a = a - b;

先减后加

bash 复制代码
int a = 1,b = 2;
a = a - b;
a = a - b;
b = a + b;

但是可能会有数据溢出的情况,可以采用下面的小魔法来交换。

两数交换,不会溢出的小魔法

bash 复制代码
int a = 1,b = 2;
a = a ^ b;
b = b ^ a;
a = a ^ b;

结论

冒泡排序虽然在最坏情况下的时间复杂度为O(n^2),但它的实现简单,对于小数据集或者基本有序的数据集,其性能表现还是相当不错的。通过优化和变体,我们可以提高冒泡排序的效率,使其在特定情况下更加实用。然而,对于大型数据集,更高效的排序算法(如快速排序、归并排序等)通常是更好的选择。

相关推荐
省四收割者4 分钟前
Go语言入门(10)-数组
数据结构·经验分享·笔记·vscode·算法·golang
lxmyzzs17 分钟前
【图像算法 - 21】慧眼识虫:基于深度学习与OpenCV的农田害虫智能识别系统
人工智能·深度学习·opencv·算法·yolo·目标检测·计算机视觉
KeithTsui18 分钟前
GCC C语言整数转换的理解(Understanding of Integer Conversions in C with GCC)
c语言·开发语言·算法
欧阳小猜2 小时前
深度学习②【优化算法(重点!)、数据获取与模型训练全解析】
人工智能·深度学习·算法
小欣加油2 小时前
leetcode 904 水果成篮
c++·算法·leetcode
有Li3 小时前
CXR-LT 2024:一场关于基于胸部X线的长尾、多标签和零样本疾病分类的MICCAI挑战赛|文献速递-深度学习人工智能医疗图像
论文阅读·人工智能·算法·医学生
君万3 小时前
【LeetCode每日一题】56. 合并区间
算法·leetcode·golang
墩墩同学3 小时前
【LeetCode题解】LeetCode 287. 寻找重复数
算法·leetcode·二分查找
小南家的青蛙3 小时前
LeetCode第55题 - 跳跃游戏
算法·leetcode·职场和发展
啊我不会诶4 小时前
CF每日4题(1500-1700)
c++·学习·算法