排序算法总结

在这里插入图片描述
在这里插入图片描述

内部/外部排序:内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。
算法的稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,则称这种排序算法是稳定的,否则称为不稳定的。

冒泡排序

思想:每次遍历不断交换最大值,排在最后一个。

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

选择排序

思想:每次遍历选出一个最小一个,排在第一位。

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

插入排序

思想:不断地从后面选一个数,插入到前面已经有序的序列里。

void insert_sort(vector<int> &nums){
    for (int i = 1; i < nums.size();i++)
    {
        int t = nums[i];
        int j = i;
        for (; j > 0&&nums[j-1]>t;j--)
        {
            nums[j] = nums[j-1];
        }
        nums[j] = t;
    }
}

希尔排序

思想:是插入排序的高效改进版本,先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。

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

归并排序

思想:拆分到单个元素,然后两个两个往上进行递归合并。

void merge(vector<int> &nums, int begin, int mid, int end){
    vector<int> left(nums.begin() + begin, nums.begin() + mid + 1);
    vector<int> right(nums.begin() + mid+1, nums.begin() + end + 1);
    int l = 0, r = 0;
    int p = begin;
    while(l+begin<=mid&&r+mid+1<=end)
    {
        if(left[l]<right[r])
            nums[p++] = left[l++];
        else
            nums[p++] = right[r++];
    }
    while(l+begin<=mid)
        nums[p++] = left[l++];
    while(r+mid+1<=end)
        nums[p++] = right[r++];
}

void merge_sort(vector<int> &nums, int begin, int end){
    if(begin>=end)
        return;
    int mid = (end - begin) / 2 + begin;
    merge_sort(nums, begin, mid);
    merge_sort(nums, mid + 1, end);
    merge(nums, begin, mid, end);
}

快速排序

思想:指定第一个数为 mid_value,排序使得 mid_value 左边的数比其小,右边的数比其大,然后分别对左边和右边进行递归排序。

void quick_sort(vector<int> &nums, int begin, int end){
    if(begin>=end)
        return;
    int l = begin;
    int r = end;
    int t = nums[begin];
    while(l<r)
    {
        while(l<r&&nums[r]>=t)
            r--;
        nums[l] = nums[r];
        while(l<r&&nums[l]<=t)
            l++;
        nums[r] = nums[l];
    }
    nums[l] = t;
    quick_sort(nums, begin, l-1);
    quick_sort(nums, l+1, end);
}

堆排序

思想:建立一个大根堆,再依次把最大的数放到数组最后。

void ajust_heap(vector<int> & nums, int l, int x)
{
    int maxn = nums[x];
    int lx = x * 2 + 1;
    int rx = x * 2 + 2;
    if(lx<=l)
        maxn = max(maxn, nums[lx]);
    if(rx<=l)
        maxn = max(maxn, nums[rx]);
    if(maxn==nums[x])
        return;
    else if(lx<=l&&maxn==nums[lx])
    {
        swap(nums[x], nums[lx]);
        ajust_heap(nums, l, lx);
    }
    else if(rx<=l&&maxn==nums[rx])
    {
        swap(nums[x], nums[rx]);
        ajust_heap(nums, l, rx);
    }

    return;
}

void heap_sort(vector<int> & nums)
{
    int l = nums.size() - 1;
    for (int i = (l - 1) / 2; i >= 0;i--)
    {
        ajust_heap(nums, l, i);
    }
    for (int i = l; i > 0;i--)
    {

        swap(nums[0],nums[i]);
        ajust_heap(nums, i-1, 0);
    }
}

资料

十大经典排序算法
排序算法总结

数组中的第K个最大元素

堆排序实现:

class Solution {
private:
    void adjust_heap(vector<int>& nums, int x){
        int n=nums.size();
        int mmax = nums[x];
        int l=x*2+1;
        int r=x*2+2;
        if(l<n)
            mmax=min(nums[l],mmax);
        if(r<n)
            mmax=min(nums[r],mmax);
        if(mmax==nums[x])
            return;
        else if(l<n&&mmax==nums[l])
        {
            swap(nums[x],nums[l]);
            adjust_heap(nums,l);
        }
        else if(r<n&&mmax==nums[r])
        {
            swap(nums[x],nums[r]);
            adjust_heap(nums,r);
        }
    }
    void build_heap(vector<int>& myheap){
        for(int i=(myheap.size()-2)/2;i>=0;i--)
            adjust_heap(myheap,i);
    }

public:
    int findKthLargest(vector<int>& nums, int k) {
        vector<int> myheap(nums.begin(),nums.begin()+k);
        build_heap(myheap);
        for(int i=k;i<nums.size();i++)
            if(nums[i]>myheap[0])
            {
                myheap[0]=nums[i];
                adjust_heap(myheap, 0);
            }
        return myheap[0];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值