八大排序——c++版

发布于:2025-04-08 ⋅ 阅读:(10) ⋅ 点赞:(0)

本次排序都是按照升序排的

冒泡排序

void bubbleSort(vector<int>& nums)
{
    int n=nums.size();
    for(int i=0;i<n-1;i++)
    {
        bool swapped=false;
        for(int j=0;j<n-1-i;j++)
        {
            if(nums[j]>nums[j+1])
            {
                swap(nums[j],nums[j+1]);
                swapped=true;
            }
        }
        if(!swapped)
            break;
    }
}
//算法原理: 一共排序n-1次,每一次排序,相邻元素两两比较,一共比较n-1-i次,最后排出一个元素放在数组末尾,n-1次后,排序完成。
//         若还没有到第n-1次排序,比较元素没有交换位置,则排序已完成,可提前结束排序。
//时间复杂度: O(N^2)
//空间复杂度: O(1)
//稳定性: 稳定

选择排序

void SelectSort(vector<int>& nums)
{
    int n=nums.size();
    for(int i=0;i<n-1;i++)
    {
        int minIndex=i;
        for(int j=i+1;j<n;j++)
        {
            if(nums[j]<nums[minIndex])
            {
                minIndex=j;
            }
            
        }
        swap(nums[i],nums[minIndex]);
    }
}
//算法原理: 需要选择n-1次基准元素,从下标为0开始选取,然后与未排序的元素比较,找到元素最小的下标,交换基准元素和最小元素,一次排序
//         已完成。一共排序n-1次。       
//时间复杂度: O(N^2)
//空间复杂度: O(1)
//稳定性: 不稳定

插入排序

void InsertSort(vector<int>& nums)
{
    int n=nums.size();
    for(int i=1;i<n;i++)
    {
        int key=nums[i],j=i-1;
        while(j>=0&&nums[j]>key)
        {
            nums[j+1]=nums[j];
            j--;
        }
        nums[j+1]=key;
    }
}
//算法原理: 从下标为1开始,令其为key,然后插入到已排序的元素中,找到应该插入的位置。     
//时间复杂度: O(N^2)
//空间复杂度: O(1)
//稳定性: 稳定

希尔排序

void ShellSort(vector<int>& nums)
{
    int n=nums.size();
    for(int gap=n/2;gap>0;gap/=2)
    {
        for(int i=gap;i<n;i++)
        {
            int key=nums[i],j=i-gap;
            while(j>=0&&nums[j]>key)
            {
                nums[j+gap]=nums[j];
                j-=gap;
            }
            nums[j+gap]=key;
        }
    }
}
//算法原理: 插入排序的优化,按照gap为间隔,每次排序是预排序,使数组趋于有序化,当gap等于1时,才是真的排序   
//时间复杂度: O(N^2)
//空间复杂度: O(1)
//稳定性: 不稳定

快速排序

快排思想:

int _QuickSort(vector<int> &nums, int left, int right)
{
    int key = left;
    left++;
    while (left <= right)
    {
        while (left <= right && nums[left] < nums[key])
            left++;
        while (left <= right && nums[right] > nums[key])
            right--;
        if (left <= right)
            swap(nums[left++], nums[right--]);
    }
    swap(nums[key], nums[right]);
    return right;
}
void QuickSort(vector<int> &nums, int left, int right)
{
    if (left > right)
        return;
    int key = _QuickSort(nums, left, right);
    QuickSort(nums, left, key - 1);
    QuickSort(nums, key + 1, right);
}
//算法原理: 任取待排序元素中的某元素作为基准元素,使左边元素都小于基准元素,右边元素都大于基准元素,然后重复该过程,直到所有元素都
//         排序完成。   
//时间复杂度: O(NlogN)
//空间复杂度: O(logN)
//稳定性: 不稳定

归并排序

void MergeSort(vector<int> &nums, int left, int right)
{
    if (left >= right) return;
    int mid = (left + right) >> 1;
    MergeSort(nums, left, mid);
    MergeSort(nums, mid + 1, right);
    vector<int> tmp(right-left+1);
    int cur1 = left, cur2 = mid + 1, i = 0;
    while (cur1 <= mid && cur2 <= right)
        tmp[i++] = nums[cur1] < nums[cur2] ? nums[cur1++] : nums[cur2++];
    while (cur1 <= mid)
        tmp[i++] = nums[cur1++];
    while (cur2 <= right)
        tmp[i++] = nums[cur2++];
    for (int i = left; i <= right; i++)
        nums[i] = tmp[i - left];
}
//算法原理: 将数组分为两部分,不断的递归,直到数组元素为1或者不能再分,然后合并两个有序数组。   
//时间复杂度: O(NlogN)
//空间复杂度: O(N)
//稳定性: 稳定

堆排序

void AdjustDown(vector<int>& nums,int n,int parent)
{
    int child=parent*2+1;
    while(child<n)
    {
        if(child+1<n && nums[child+1]>nums[child]) child=child+1;
        if(nums[child]>nums[parent])
        {
            swap(nums[child],nums[parent]);
            parent=child;
            child=parent*2+1;
        }
        else
        {
            break;
        }
    }
}
void HeapSort(vector<int>& nums)
{
    int n=nums.size();
    //构建大根堆,从最后一个非叶子节点开始
    for(int i=(n-1-1)/2;i>=0;i--)
    {
        AdjustDown(nums,n,i);
    }
    //排序
    int end=n-1;
    while(end>=0)
    {
        swap(nums[0],nums[end]);
        AdjustDown(nums,end,0);
        end--;
    }
}
//算法原理: 先构建最大堆,然后交换堆顶元素和最后一个元素,这样最后一个元素就是最大的了,然后再建堆,这样不断循环。
//时间复杂度: O(NlogN)
//空间复杂度: O(N)
//稳定性: 稳定

基数排序

void RadixSort(std::vector<int>& nums) {
    int maxVal=*max_element(nums.begin(),nums.end());
    int maxDigits=0;
    while(maxVal)
    {
        maxVal/=10;
        maxDigits++;
    }
    vector<queue<int>> buckets(10);
    for(int i=0;i<maxDigits;i++)
    {
        for(int num : nums)
        {
            int bucketIndex=num/static_cast<int>(pow(10,i))%10;
            buckets[bucketIndex].push(num);
        }
        int index=0;
        for(auto& bucket : buckets)
        {
            while(!bucket.empty())
            {
                nums[index++]=bucket.front();
                bucket.pop();
            }
        }
    }
}
//算法原理:  按照位数排序,按照位数把元素分配到对应的桶中,然后依据先进先出的顺序再收集到数组中,这样依次排个位,十位,百位。
//时间复杂度: O(NlogN)
//空间复杂度: O(N)
//稳定性: 稳定