排序算法-冒泡排序、插入排序、快速排序、归并排序

本文深入解析了四种经典的排序算法:冒泡排序、插入排序、快速排序和归并排序。详细介绍了每种算法的实现原理、时间复杂度、空间复杂度及稳定性,同时提供了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

排序算法-冒泡排序、插入排序、快速排序、归并排序

一、冒泡排序(BubbleSort)
1.最坏和最好情况下时间复杂度都为O(nn),空间复杂度为O(1),稳定的排序算法
思路
从列表第一个位置(最后一个位置)依次循环遍历列表,对比剩余没有排序的元素,把最小的元素(最大的元素)依次放置在列表的前端(后端)。
二、插入排序(InsertSort)
1.最好的情况下,时间复杂度为O(n),平均时间复杂度为O(n
n)。空间复杂度为O(n)
思路
从第一个位置遍历列表中的元素,对新遍历到的元素,在之前以前排序好的列表中找到合适的位置,并且把大于该元素的值全部向后移动,然后把该元素插入。
三、快速排序(QuickSort)
1.平均时间复杂度为O(nlogn),最坏的情况下O(n*n),空间复杂度为O(logn)
思路
1.从列别第一个位置开始,为列表第一个位置的元素找到合适的位置,使得小于该数值的数被放在左边,大于该数值的数被放在右边,列表被分为左右两段。
2.对于刚才遍历得到的两段列表,依次判断左右结点是否是同一个,若是同一个,则return,否则对两端列表进行步骤1的操作。
3.依次递归循环执行步骤2,直到所有数值都被放到合适的位置。
四、归并排序(MergeSort)
1.归并排序时间复杂度为O(nlogn),空间复杂度为O(n)
思路
1.分而治之的思想
2.首先把一个列表两两分割,然后对分割后的列表再依次进行两两分割,直到分割到最后都只剩一个数值为止
3.对于分割之后的列表,采用两两合并并且排序的原则,直到最后的列表完全有序位置。
代码

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

//BubbleSort
void BubbleSort(vector<int> &nums){
    for(int i = 0; i < nums.size(); i++){
        for(int j = i + 1; j < nums.size(); j++){
            if(nums[i] > nums[j]){
                swap(nums[i], nums[j]);
            }
        }
    }
}

//InsertSort
void InsertSort(vector<int> &nums){
    for(int i = 1; i < nums.size(); i++){
        for(int j = i; j > 0; j--){
            if(nums[j] < nums[j - 1]){
                swap(nums[j], nums[j - 1]);
            }else{
                break;
            }
        }
    }
}

//QuickSort
int numSort(vector<int> &nums, int left, int right){
    int tmp = nums[left];
    while(left < right){
        while(left < right && nums[right] >= tmp){
            right--;
        }
        nums[left] = nums[right];
        while(left < right && nums[left] <= tmp){
            left++;
        }
        nums[right] = nums[left];
    }
    nums[left] = tmp;
    return left;
}
void QuickSort(vector<int> &nums, int left, int right){
    if(right > left){
        int mid = numSort(nums, left, right);
        QuickSort(nums, left, mid - 1);
        QuickSort(nums, mid + 1, right);
    }
}

//Merge Sort
void Merge(vector<int> &nums, int left, int mid, int right){
    vector<int> temp;
    int i = left, j = mid + 1;
    while(i <= mid  || j <= right){
        if(i > mid){
            temp.push_back(nums[j++]);
        }else if(j > right){
            temp.push_back(nums[i++]);
        }else{
            if(nums[i] > nums[j]){
                temp.push_back(nums[j++]);
            }else{
                temp.push_back(nums[i++]);
            }
        }
    }
    j = 0;
    for(int i = left; i <= right; i++){
        nums[i] = temp[j++];
    }
}
void MergeSort(vector<int> &nums, int left, int right){
    if(right > left){
        int mid = left + (right - left) / 2;
        MergeSort(nums, left, mid);
        MergeSort(nums, mid + 1, right);
        Merge(nums, left, mid, right);
    }
}

int main(){
    int n;
    vector<int> nums;
    int num;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> num;
        nums.push_back(num);
    }
    //冒泡排序,稳定的排序算法,时间复杂度为O(n*n)
    //BubbleSort(nums);
    //插入排序,稳定的排序算法,时间复杂度为O(n*n)
    //InsertSort(nums);
    //快速排序, 不稳定的排序算法,时间复杂度为O(nlogn)
    //QuickSort(nums, 0, nums.size() - 1);
    //归并排序,分而治之(先分后合并),, 不稳定的排序算法,时间复杂度为O(nlogn)
    //MergeSort(nums, 0, nums.size() - 1);
    for(int i = 0; i < n; i++){
        cout << nums[i] << " ";
    }
    cout<<endl;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值