C++ 六大排序 五大算法

排序算法

冒泡排序

/*
冒泡排序
从数组最左端开始向右遍历,依次比较相邻元素大小,如果“左元素 > 右元素”就交换二者。
遍历完成后,最大的元素会被移动到数组的最右端。

1.首先,对n个元素执行“冒泡”,将数组的最大元素交换至正确位置。
2.接下来,对剩余n-1个元素执行“冒泡”,将第二大元素交换至正确位置
3.以此类推,经过n-1轮“冒泡”后,前n-1大的元素都被交换至正确位置。
4.仅剩的一个元素必定是最小元素,无须排序,因此数组排序完成

*/
void bubbleSort(std::vector<int>& arr) {
   
   
    int n = arr.size();
    for (int i = 0; i < n - 1; ++i) {
   
   
        bool is_swap = false;
        for (int j = 0; j < n - 1 - i; ++j) {
   
   
            if (arr[j] > arr[j + 1]) {
   
   
                std::swap(arr[j], arr[j + 1]);
                is_swap = true;
            }
        }
        if (!is_swap) break;
    }
}

插入排序





/*
插入排序
在未排序区间选择一个基准元素,
将该元素与其左侧已排序区间的元素逐一比较大小,并将该元素插入到正确的位置。

1.初始状态下,数组的第 1 个元素已完成排序。
2.选取数组的第 2 个元素作为 base ,将其插入到正确位置后,数组的前 2 个元素已排序。
3.选取第 3 个元素作为 base ,将其插入到正确位置后,数组的前 3 个元素已排序。
4.以此类推,在最后一轮中,选取最后一个元素作为 base ,将其插入到正确位置后,所有元素均已排序。

*/
void insertionSort(std::vector<int>& arr) {
   
   
    int n = arr.size();
    for(int i = 1; i < n; ++i) {
   
   
        for (int j = i; j > 0 && arr[j] < arr[j - 1]; --j) {
   
   
            std::swap(arr[j], arr[j - 1]);
        }
    }
}

选择排序

/* 
选择排序
开启一个循环,每轮从未排序区间选择最小的元素,将其放到已排序区间的末尾。

1.初始状态下,所有元素未排序,即未排序(索引)区间为[0,n-1].
2.选取区间[0,n-1]中的最小元素,将其与索引0处的元素交换。完成后,数组前 1 个元素已排序。
3.选取区间[1,n-1]中的最小元素,将其与索引1处的元素交换。完成后,数组前 2 个元素已排序。
4.以此类推。经过n-1轮选择与交换后,数组前n-1个元素已排序。
5.仅剩的一个元素必定是最大元素,无须排序,因此数组排序完成。

*/
void selectionSort(std::vector<int>& arr) {
   
   
    int n = arr.size();
    for (int i = 0; i < n - 1; ++i) {
   
   
        int mid = i;
        for (int j = i + 1; j < n; ++j) {
   
   
            if (arr[j] < arr[mid]) {
   
   
                mid = j;
            }
        }
        std::swap(arr[i], arr[mid]);
    }
}

快速排序

/* 哨兵划分 */
int partition(vector<int> &nums, int left, int right) {
   
   
    // 以 nums[left] 为基准数
    int i = left, j = right;
    while (i < j) {
   
   
        while (i < j && nums[j] >= nums[left])
            j--; // 从右向左找首个小于基准数的元素
        while (i < j && nums[i] <= nums[left])
            i++;          // 从左向右找首个大于基准数的元素
        swap(nums, i, j); // 交换这两个元素
    }
    swap(nums, i, left); // 将基准数交换至两子数组的分界线
    return i;            // 返回基准数的索引
}

// 选择数组中的某个元素作为“基准数”,
// 将所有小于基准数的元素移到其左侧,而大于基准数的元素移到其右侧。
/*

1.选取数组最左端元素作为基准数,初始化两个指针 i 和 j 分别指向数组的两端。
2.设置一个循环,在每轮中使用 i(j)分别寻找第一个比基准数大(小)的元素,然后交换这两个元素。
3.循环执行步骤 2. ,直到 i 和 j 相遇时停止,最后将基准数交换至两个子数组的分界线。

*/
/* 快速排序 */
void quickSort(vector<int> &nums, int left, int right) {
   
   
    // 子数组长度为 1 时终止递归
    if (left >= right)
        return;
    // 哨兵划分
    int pivot = partition(nums, left, right);
    // 递归左子数组、右子数组
    quickSort(nums, left, pivot - 1);
    quickSort(nums, pivot + 1, right);
}

归并排序

* 合并左子数组和右子数组 */
void merge(vector<int> &nums, int left, int mid, int right) {
   
   
    // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
    // 创建一个临时数组 tmp ,用于存放合并后的结果
    vector<int> tmp(right - left + 1);
    // 初始化左子数组和右子数组的起始索引
    int i = left, j = mid + 1, k = 0;
    // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
    while (i <= mid && j <= right) {
   
   
        if (nums[i] <= nums[j])
            tmp[k++] = nums[i++];
        else
            tmp[k++] = nums[j++
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值