【造轮子】实现冒泡排序、选择排序(C++)

本文详细介绍了冒泡排序和选择排序的算法原理、实例分析及C++实现,包括每种排序方法的遍历过程和复杂度分析。冒泡排序是一种稳定排序,时间复杂度为O(n^2),而选择排序则为非稳定排序,同样具有O(n^2)的时间复杂度。
摘要由CSDN通过智能技术生成

1. 冒泡排序

1.1 算法原理

  • 核心思想

多次遍历,每次遍历把两相邻数之间相比较,如果大数在前,小数在后,则交换。每次遍历后当前遍历区间内最大的元素会被放到区间的末尾。

  • 算法过程

第一遍遍历区间为 [0, N-1],两个相邻元素进行比较,需使之维持较小元素在前,较大元素在后。遍历完后,数组中最大的元素会被放到数组的末尾位置,然后进行第二遍遍历。第二遍遍历区间为 [0, N-2],操作方法相同。遍历完后,数组中第二大的元素被会放到数组倒数二个位置,然后进行第三遍遍历。以此类推,直至遍历区间缩小到一个数或遍历一遍后都没有发生元素交换时,排序完成。

  • 复杂度分析

时间复杂度 O(n^2),空间复杂度 O(1),为稳定排序。

1.2 实例

  • 原数组为 [5, 3, 9, 1, 2]
  • 第一遍遍历区间为 [0, 4],结果为 [3, 5, 1, 2, 9]
  • 第二遍遍历区间为 [0, 3],结果为 [3, 1, 2, 5, 9]
  • 第三遍遍历区间为 [0, 2],结果为 [1, 2, 3, 5, 9]
  • 第四遍遍历区间为 [0, 1],结果为 [1, 2, 3, 5, 9]

1.3 示例程序

void Swap(int& x, int& y)
{
    int tmp = x;
    x = y;
    y = tmp;
}

void BubbleSort(vector<int>& nums) 
{
    if (nums.size() < 2)
    {
        return;
    }

    bool changed = true;        // 保证至少进行一遍比较
    for (int i = 0; i < nums.size() && true == changed; i++)
    {
        changed = false;
        for (int j = 0; j < nums.size() - i - 1; j++)
        {
            if (nums[j + 1] < nums[j])
            {
                Swap(nums[j + 1], nums[j])
                changed = true;
            }
        }
    }
}

2. 选择排序

2.1 算法原理

  • 核心思想

多次遍历,每次遍历记录遍历区间内的最小元素,遍历后把最小元素放置到区间的开头。

  • 算法过程

第一遍遍历区间为 [0, N-1],遍历过程记录最小值的元素及其下标。遍历完后,把最小值元素与数组首个元素交换,然后进行第二遍遍历。第二遍遍历区间为 [1, N-1],操作方法相同。遍历完后,把最小值元素与数组第二位置的元素交换,然后进行第三遍遍历。以此类推,直至遍历区间缩小到一个数时,排序完成。

  • 复杂度分析

时间复杂度 O(n^2),空间复杂度 O(1),为非稳定排序。

2.2 实例

  • 原数组为 [5, 3, 9, 1, 2]
  • 第一遍遍历区间为 [0, 4],结果为 [1, 3, 9, 5, 2]
  • 第二遍遍历区间为 [1, 4],结果为 [1, 2, 9, 5, 3]
  • 第三遍遍历区间为 [2, 4],结果为 [1, 2, 3, 5, 9]
  • 第四遍遍历区间为 [3, 4],结果为 [1, 2, 3, 5, 9]

2.3 示例程序

void Swap(int& x, int& y)
{
    int tmp = x;
    x = y;
    y = tmp;
}

void SelectionSort(vector<int>& nums) 
{
    if (nums.size() < 2)
    {
        return;
    }

    for (int i = 0; i < nums.size() - 1; i++)
    {
        int min_index = i;
        for (int j = i + 1; j < nums.size(); j++)
        {
            min_index = nums[min_index] > nums[j] ? j : min_index;
        }
        if (min_index != i)
        {
            Swap(nums[i], nums[min_index]);
        }
    }
}

更多造轮子系列博文

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值