基本排序算法之冒泡排序

冒泡排序是交换排序的一种。

所谓交换,是指根据序列中的两个元素关键字的比较结果来对换这两个记录在序列中的位置。基于交换的排序算法很多,包括冒泡和快排。

算法思想

从后往前(或从前往后)两两比较相邻元素的值,若为逆序,则交换它们,直到序列比较完。我们称它为第一趟冒泡,结果是将最小的元素交换到待排序列的第一个位置(或将最大的元素交换到待排序列的最后一个位置),下一趟冒泡时,前一趟确定的最小元素(或最大元素)不再参与比较,每趟冒泡的结果是把序列中的最小元素(或最大元素)放到了序列的最终位置…因此这样最多需要n-1趟冒泡就能所有元素排好序。

优化

使用布尔标记来记录交换动作的出现,这一修改只是改进了最好情况下的行为。

实现

Python实现:

def swap(lyst:list,i:int,j:int)->None:
    tmp = lyst[i]
    lyst[i] = lyst[j]
    lyst[j] = tmp

    
def bubbleSort(lyst: list)->list:
    n = len(lyst)
    while n>1:
        flag = False
        for i in range(1,n):
            if lyst[i] <lyst[i-1]:
                swap(lyst,i,i-1)
                flag = True
        if flag== False: return lyst
        n -= 1
    return lyst

print(bubbleSort([9,1,2,5,5,4,8,6,3,5]))
print(bubbleSort([2,3,5,6,8]))

C++实现:

#include <iostream>
#include <vector>
using namespace std;
void swap(vector<int>& lyst, int i,int j){
    int tmp = lyst[i];
    lyst[i] = lyst[j];
    lyst[j] = tmp;

}
vector<int> bubbleSort(vector<int>& lyst){
    int n = lyst.size();
    while(n>1){
        bool flag = false;
        for (int i =1;i<n;i++){
            if(lyst[i-1]>lyst[i]) {
                swap(lyst,i,i-1);
                flag = true;
            }
        }
        if(flag==false) return lyst;
        n--;
    }
    return lyst;
    }

int main() {
    vector<int> test = {1,2,3,4};
    vector<int> res = bubbleSort(test);
    for (int i = 0; i < res.size(); i++){
        cout << res[i] << " ";
    }
    return 0;
}

算法分析

时间: 当初始序列有序时,第一趟冒泡后flag依然为false(本趟冒泡没有元素交换),从而直接跳出循环,比较次数为n-1,移动次数为0,所以最好情况下的时间复杂度为o(n)。
当初始序列逆序时,需要进行n-1趟排序,第i趟排序需要进行 n − i n-i ni次关键字的比较,而且每次都必须移动3次进行交换元素位置,所以,比较次数为 ∑ i = 1 n − 1 ( n − i ) = n ( n − 1 ) 2 \sum^{n-1}_{i=1}(n-i)=\frac{n(n-1)}{2} i=1n1(ni)=2n(n1),移动次数为 ∑ i = 1 n − 1 3 ( n − i ) = 3 n ( n − 1 ) 2 \sum^{n-1}_{i=1}3(n-i)=\frac{3n(n-1)}{2} i=1n13(ni)=23n(n1)。时间复杂度为o( n 2 n^2 n2)。
空间: 仅使用了常数个辅助单元,因而空间复杂度为o(1)。
稳定性: 由于i>j,且L(i)=L(j)时,不会发生交换,因而稳定。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值