C++算法基础之手写常见排序算法 堆排序 归并排序 快速排序 自定义排序(真题)

  • Post author:
  • Post category:其他


排序算法是所有算法的基础,如果真正徒手开始写还是要熟练掌握的,从零开始而不是直接在LeetCode上写。

下面的代码都是在VS Code中能直接运行的!


堆排序 堆整理后 最大的元素在头


时间复杂度O(n logn) 空间复杂度 O(1)


注意swap函数中的形参!

#include<iostream>
#include<vector>
using namespace std;
//swap函数必须 是形参 否则调用后没有任何作用!
void swap(int& i, int& j)
{
    int tmp = j;
    j = i;
    i = tmp;
}
void heapify(vector<int>&nums, int i, int end)
{
    int large = 0;
    int lSon = 0, rSon = 0;
    for(; (i<<1)+1 <= end;)
    {
        lSon = (i<<1)+1;
        rSon = (i<<1)+2;
        large = i;
        if(nums[lSon] > nums[large])
        {
            large = lSon;
        }
        if(rSon <= end && nums[rSon] > nums[large])
        {
            large = rSon;
        }
        if(large != i)
        {
            swap(nums[large],nums[i]);
            i = large;
        }
        else
            break;        
    }
}
void buildHeap(vector<int>& nums)
{
    int end = nums.size() - 1;
    for(int i = end/2; i >= 0; i--)
    {
        heapify(nums,i,end);
    }
}

void heapSort(vector<int>& nums)
{
    int end = nums.size()-1;
    buildHeap(nums);
    for(; end >= 0;)
    {
        swap(nums[0],nums[end--]);
        heapify(nums,0,end);
    }
}
int main()
{
    int n ;
    cin >> n;
    vector<int> nums;
    nums.resize(n);
    for(int i = 0; i < n; i++)
    {
        cin >> nums[i];
    }
    heapSort(nums);
    for(int i = 0; i < n; i++)
    {
        cout << nums[i] << " ";
    }
    return 0;
}


归并排序 2分思想


时间复杂度O(n logn) 空间复杂度 O(n) 因为需要用到额外的空间tmp

#include<iostream>
#include<vector>
using namespace std;
vector<int> tmp;
void mergeSort(vector<int>& nums, int start, int end)
{
    if(start >= end) return;
    int mid = (start+end)/2;
    mergeSort(nums,start,mid);
    mergeSort(nums,mid+1,end);
    int cnt = 0;
    int i = start, j = mid+1;
    while(i <= mid && j <= end)
    {
        if(nums[i] <= nums[j])
            tmp[cnt++] = nums[i++];
        else
            tmp[cnt++] = nums[j++];
            
    }
    while(i <= mid)
    {
        tmp[cnt++] = nums[i++];            
    }
    while(j <= end)
    {
        tmp[cnt++] = nums[j++];      
    }
    i = start;
    for(int k = 0; k < cnt; k++)
    {
        nums[i++] = tmp[k];
    }
}
int main()
{
    int n ;
    cin >> n;
    vector<int> nums(n);
    tmp.resize(n);
    for(int i = 0; i < n; i++)
    {
        cin >> nums[i];
    }
    mergeSort(nums,0,n-1);
    for(int i = 0; i < n; i++)
    {
        cout << nums[i] << " ";
    }
    return 0;
}


快速排序 分段思想


随机选择 中间点pivot


不稳定的排序算法!


时间复杂度 最好 O(n logn)  最坏 O(n n) 空间复杂度 O(h)  递归层数h 最好 logn 最坏 n

#include<iostream>
#include<vector>
using namespace std;
void quickSort(vector<int>& nums, int start, int end)
{
    if(start >= end) return;
    int ind = rand()%(end - start + 1) + start;
    swap(nums[ind],nums[start]);
    int pivot = nums[start];
    int i = start, j = end;
    while(i < j)
    {
        while(i < j && nums[j] >= pivot)
            j--;
        nums[i] = nums[j];
        while(i < j && nums[i] <= pivot)
            i++;
        nums[j] = nums[i]; 
    }
    nums[i] = pivot;
    quickSort(nums,start,i-1);
    quickSort(nums,i+1,end);
}
int main()
{
    int n;
    cin >> n;
    srand(0);//随机种子
    vector<int> nums;
    nums.resize(n);
    for(int i = 0; i < n; i++)
    {
        cin >> nums[i];
    }
    quickSort(nums,0,n-1);
    for(int k : nums)
        cout <<  k <<  " ";
    return 0;
}


插入排序

从index = 1开始,依次上移 并选择合适的位置插入

void insertSort(vector<int>& nums)
    {
        int n = nums.size();
        for(int i = 1; i < n; i++)
        {
            int j = i-1, tmp = nums[i];
            while(j >= 0 && nums[j] > tmp)
            {
                nums[j+1] = nums[j];
                j--;
            }
            nums[j+1] = tmp;            
        }
    }


选择排序

每次选择最小的放在对应位置

//选择排序 每次选择最小的数值 到最前面
void selectSort(vector<int>& nums)
{
        int n = nums.size();
        for(int i = 0; i < n; i++)
        {
            int min_index = i;
            for(int j = i + 1; j < n; j++)
            {
                if(nums[j] < nums[min_index])
                    min_index = j;
            }
            if(i < min_index)
                swap(nums[i],nums[min_index]);
        }
}

冒泡排序

//冒泡排序
    void bubbleSort(vector<int>& nums)
    {
        int n = nums.size();
        for(int i = 0; i < n; i++)
        {
            bool f = false;
            for(int j = 1; j < n-i; j++)
            {
                if(nums[j-1] > nums[j])
                {
                    swap(nums[j-1],nums[j]);
                    f = true;
                }                    
            }
            cout << i << endl;
            if(!f) break;
        }
    }

自定义排序算法

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool compare(const vector<int>& a, const vector<int>& b)
{
    return a[0] < b[0];
}
int main()
{
    int n;
    cin >> n;
    vector<vector<int>> nums(n,vector<int>(2));
    for(int i = 0; i < n; i++)
    {
        cin >> nums[i][0] >> nums[i][1];
    }
    sort(nums.begin(),nums.end(),compare);
    for(int i = 0; i < n; i++)
    {
        cout << nums[i][0] << " " << nums[i][1] << endl;
    }
    return 0;
}



版权声明:本文为li4692625原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。