数据结构算法-冒泡排序算法

引言

虽然选择排序好用 ,但有点问题 也就是频繁找最大值下标 放到 未排序的后面

因为每次需要扫描整个未排序序列,找到最大值或最小值的下标,并将其交换到未排序序列的最后一个位置。这样做的问题在于,在后面的迭代中,我们仍然需要扫描整个未排序序列,包括已经排序好的部分,这是浪费时间的。

另外,选择排序是不稳定的排序算法,因为在找到最大值或最小值的下标时,并没有考虑值相同的元素的顺序。如果有多个相同值的元素,交换它们的位置可能会打乱它们的相对顺序

也就是说 相同的元素也交换 可能位置有变化

对于相同的元素,它们在排序后的位置可能会改变,因为冒泡排序会将相邻的两个元素进行比较和交换,这样相同的元素就可能会在排序过程中交换位置。对于选择排序而言,它在找到最大值或最小值的下标时,并没有考虑值相同的元素的顺序,因此如果有多个相同值的元素,交换它们的位置可能会打乱它们的相对顺序。因此选择排序也是不稳定的排序算法。

冒泡排序算法思想


到i=2的时候 已经是排序了 那么这里应该如何优化?

如果有一种机制 一开始默认已排序 在内层循环判断第一个比第二大发生交换的时候 制定为false

内层循环结束判断这个排序标志 为真排序完成直接退出外层循环

冒泡排序的基本思想是,通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底的气泡一样逐渐向上冒。

在这个过程中,每次内循环都会将当前未排序部分的最大元素"冒泡"到其最终位置。因此,每次外循环之后,未排序部分的元素数目会减少一个。

冒泡排序算法专区

cpp 复制代码
// 定义一个名为bubbleSort的函数,它接收两个参数:一个名为arr的整数数组和一个名为size的整数,表示数组的大小  
void bubbleSort(int arr[], int size) {  
  
    // 外层循环,用于控制排序的轮数。因为每一轮都会将最大的元素移动到数组的末尾,所以最多需要size-1轮。  
    for (int i = 0; i < size - 1; i++) {    
          
        // 内层循环,用于在每一轮中逐一比较相邻的元素。由于每一轮都会确保最大的元素移动到其应在的位置,因此内层循环只需要遍历到"size-1-i"即可。  
        for (int j = 0; j < size - 1 - i; j++) {    
              
            // 如果当前元素大于下一个元素,则交换它们的位置。这是冒泡排序的核心操作。  
            if (arr[j] > arr[j+1]) {    
                  
                // 调用swap函数交换两个元素的值。
                swap(arr[j], arr[j+1]);    
            }    
        }    
    }    
}
}

优化:

cpp 复制代码
// 定义一个名为bubbleSort的函数,接收一个整数数组arr和数组的大小size作为参数  
void bubbleSort(int arr[], int size) {  
  
    // 外层循环,遍历整个数组  
    for (int i = 0; i < size - 1; i++) {    
          
        // 定义一个布尔变量swapped,用于记录是否发生了交换  
        bool swapped = false; // 用于记录是否发生了交换    
          
        // 内层循环,比较相邻的元素并进行交换  
        for (int j = 0; j < size - 1 - i; j++) {    
              
            // 如果当前元素大于下一个元素,则进行交换  
            if (arr[j] > arr[j+1]) {    
                  
                // 调用swap函数交换两个元素的值  
                swap(arr[j], arr[j+1]);    
                  
                // 将swapped设为true,表示发生了交换    
                swapped = true; // 发生了交换,将swapped设为true    
            }    
        }    
          
        // 如果内层循环结束时,swapped仍然为false,说明数组已经是有序的,直接退出外层循环  
        if (!swapped) break; // 如果内层循环结束时,swapped仍然为false,说明数组已经是有序的,直接退出外层循环    
    }    
}

升/降 序通用

cpp 复制代码
// 定义一个函数 BubbleSort,接受一个整数数组 arr,数组的大小 size,和一个比较函数 cmp 作为参数。这个函数用来对数组进行冒泡排序。  
void  BubbleSort(int arr[], int size, bool(*cmp)(const int&, const int&)) {  
  
    // 检查传入的比较函数是否为空。如果为空,则直接返回,不进行任何操作。  
    if (cmp == nullptr) {  
        return;  
    }  
  
    // 开始进行外层循环,从数组的第一个元素到倒数第二个元素(i 从 0 到 size-2)  
    for (int  i = 0; i < size-1; i++){  
  
        // 定义一个布尔变量 IsSort,初始值为 true。这个变量用来检查数组是否已经有序。  
        bool IsSort = true;  
  
        // 进行内层循环,从数组的第二个元素开始到倒数第三个元素(j 从 0 到 size-1-i)  
        for (int j= 0; j < size-1-i; j++){  
  
            // 使用比较函数 cmp 来判断 arr[j] 是否大于 arr[j + 1]。如果大于,则交换这两个元素的位置,并将 IsSort 设为 false。  
            if (cmp(arr[j], arr[j + 1])) {  
                swap(arr[j], arr[j + 1]);  
                IsSort = false;  
            }  
        }  
  
        // 如果 IsSort 仍然为 true,说明这个位置的元素已经是有序的,可以结束内层循环。  
        if (IsSort)	{  
            break;  
        }  
    }  
}  
  
// 定义一个函数 GreaterCmp,接受两个整数作为参数,如果第一个整数大于第二个整数,返回 true,否则返回 false。这个函数用于比较两个整数的大小。  
bool GreaterCmp(const int& val1, const int &val2) {  
    return val1 > val2;  
}  
  
// 定义一个函数 LessCmp,接受两个整数作为参数,如果第一个整数小于第二个整数,返回 true,否则返回 false。这个函数用于比较两个整数的大小。  
bool LessCmp(const int& val1, const int& val2) {  
    return val1 < val2;  
}
相关推荐
阑梦清川5 分钟前
数学建模启发式算法篇(一)---遗传算法
算法·数学建模·启发式算法
ErvinHowell19 分钟前
文件MD5生成性能大提升!如何实现分片与Worker优化
前端·vue.js·算法
用户405478783748221 分钟前
深度学习笔记 - Pytorch自搭建VGG-16模型实现人脸识别
算法
很透彻26 分钟前
【网络】传输层协议TCP(下)
网络·c++·网络协议·tcp/ip
益达爱喝芬达33 分钟前
力扣11.3
算法·leetcode
y_m_h34 分钟前
leetcode912.排序数组的题解
数据结构·算法
passer__jw76734 分钟前
【LeetCode】【算法】406. 根据身高重建队列
算法·leetcode
1 9 J34 分钟前
数据结构 C/C++(实验三:队列)
c语言·数据结构·c++·算法
sweetheart7-735 分钟前
LeetCode17. 电话号码的字母组合(2024秋季每日一题 59)
算法·深度优先·力扣·dfs
想做白天梦35 分钟前
LeetCode :150. 逆波兰表达式求值(含求后缀表达式和中缀转后缀表达式)
java·前端·算法