1排大序算法总结

排序算法总结

以剑指offer的最小K个数为列

详细介绍见:https://www.cnblogs.com/onepixel/p/7674659.html

插曲1:基数排序,计数排序,桶排序区别

“首先,基数排序和计数排序都可以看作是桶排序。 计数排序本质上是一种特殊的桶排序,当桶的个数取最大( maxV-minV+1 )的时候,就变成了计数排序。 基数排序也是一种桶排序。桶排序是按值区间划分桶,基数排序是按数位来划分;基数排序可以看做是多轮桶排序,每个数位上都进行一轮桶排序。 

题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

方法1;冒泡排序

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //int* temp = new int[input.size()]
        vector<int> res;
        if(k>input.size())
            return res;
        for(int i=1;i<input.size();i++)//冒泡排序
        {
            for(int j=0;j<input.size()-i;j++)
            {
                if(input[j]>input[j+1])
                    swap(input[j],input[j+1]);
            }
        }
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
    void swap(int &a,int &b)//交换两个数
    {
        int c=a;
        a=b;
        b=c;
    }
};

方法2:快排

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //int* temp = new int[input.size()]
        vector<int> res;
        if(k>input.size())
            return res;
        Quicksort(input,0,input.size());
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
    void Quicksort(vector<int> &input,int left,int right)
    {
        if(left<right)
        {
            int p=left;
            int q=left+1;
            int tag=input[left];
            while(q<right)
            {
                if(input[q]<input[left])
                {
                    p++;
                    int temp=input[q];
                    input[q]=input[p];
                    input[p]=temp;
                   // swap(input[q],input[p]);
                }
                q++;
            }
            input[left]=input[p];
            input[p]=tag;
            Quicksort(input,left,p);
            Quicksort(input,p+1,right);
        }
    }
};

方法3;选择排序

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //int* temp = new int[input.size()]
        vector<int> res;
        if(k>input.size())
            return res;
        for(int i=0;i+1<input.size();i++)
        {    //注意只能写成i<input.size()-1的形式,会报错       
            int min=i;
            for(int j=i+1;j<input.size();j++)//选择排序
            {
                if(input[j]<input[min])
                    min=j;
            }
            if(i!=min)
            swap(input[i],input[min]);
        }
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
    void swap(int &a,int &b)
    {
        int c=a;
        a=b;
        b=c;
    }
};

方法四:插入排序

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //int* temp = new int[input.size()]
        vector<int> res;
        if(k>input.size())
            return res;
        for(int i=1;i<input.size();i++)
        {//插入排序
            int pre=i-1;
            int cur=input[i];
            while(pre>=0&&input[pre]>cur)
            {
                input[pre+1]=input[pre];
                pre--;
            }
            input[pre+1]=cur;
        }      
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
};

方法5:希尔(shell)排序

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //int* temp = new int[input.size()]
        vector<int> res;
        if(k>input.size())
            return res;
        int gap = input.size()/2+1;//当取2时可以加1也可不加,取3时一定得加
        while(gap)
        {//shell排序
            for(int i=gap;i<input.size();i++)
            {
                int temp=input[i];
                int j=i;
                while(j>=gap&&temp<input[j-gap])
                {
                    input[j]=input[j-gap];
                    j-=gap;
                }
                input[j]=temp;
            }
            gap=gap/2;
        }
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
};

方法6:归并排序

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //int* temp = new int[input.size()]
        vector<int> res;
        if(k>input.size())
            return res;
        MergeSort(input,0,input.size()-1);
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
    void MergeSort(vector<int> &input,int begin,int end)
    {//归并排序
        if(input.empty()||begin>=end) return ;
        int mid=(begin+end)/2;//分解从两部分
        MergeSort(input,begin,mid);
        MergeSort(input,mid+1,end);
        Merge(input,begin,mid,end);//融合
    }
    void Merge(vector<int> &input,int begin,int mid,int end)
    {
        int i=begin;
        int j=mid+1;
        vector<int> temp;
        while(i<=mid&&j<=end)
        {
            if(input[i]<input[j])
                temp.push_back(input[i++]);
            else
                temp.push_back(input[j++]);
        }
        while(i<=mid)
            temp.push_back(input[i++]);
        while(j<=end)
            temp.push_back(input[j++]);
        for(int i=0;i<temp.size();i++)
        {
            input[begin+i]=temp[i];
        }
    }
};


方法7:计数排序

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //int* temp = new int[input.size()]
        vector<int> res;
        if(k>input.size())
            return res;
        CountSort(input);
        for(int i=0;i<k;i++)
            res.push_back(input[i]);
        return res;
    }
    void CountSort(vector<int> &input)
    {
        if(input.empty()) return ;
        int max=input[0];
        for(int i=1;i<input.size();i++)
        {//计数排序
            if(input[i]>max)
                max=input[i];//统计最大值
        }
        vector<int> temp(max+1);//默认初始化为0
        for(int i=0;i<input.size();i++)
        {
            temp[input[i]]++;//统计每个值出现的次数
        }
        int index=0;
        for(int i=0;i<max+1;i++)//
        {
            for(int j=0;j<temp[i];j++)
                input[index++]=i;//通过下标排序
        }
    }

};

堆排序

void adjust(vector<int> &arr, int len, int index)

{

    int left = 2*index + 1; // index的左子节点

    int right = 2*index + 2;// index的右子节点

 

    int maxIdx = index;

    if(left<len && arr[left] > arr[maxIdx])     maxIdx = left;

    if(right<len && arr[right] > arr[maxIdx])     maxIdx = right;

 

    if(maxIdx != index)

    {

        swap(arr[maxIdx], arr[index]);

        adjust(arr, len, maxIdx);

    }

 

}

 

// 堆排序

void heapSort(vector<int> &arr, int size)

{

    // 构建大根堆(从最后一个非叶子节点向上)

    for(int i=size/2 - 1; i >= 0; i--)

    {

        adjust(arr, size, i);

    }

 

    // 调整大根堆

    for(int i = size - 1; i >= 1; i--)

    {

        swap(arr[0], arr[i]);           // 将当前最大的放置到数组末尾

        adjust(arr, i, 0);              // 将未完成排序的部分继续进行堆排序

    }

}

归并排序 O(1)

 #include <iostream>
 #include <cstdlib>
 using namespace std;
 void print(int *arr, int start, int end)
 {
    for (int i = start; i <= end; ++i)
        cout << arr[i] << ' ';
    cout << endl;
 }
 void randData(int *arr, int start, int end)
 {
    for (int i = start; i <= end; ++i)
        arr[i] = rand() % 20; 
    print(arr, start, end);
 }
 
void merge(int *arr, int start, int mid, int end)
{
    int i, j, k, key;
    i = start;
    j = mid;
    while (i < j && j <= end)  //当i等于j或者j到达末尾时终止
    {
        if (arr[i] > arr[j])
        {    
            k = j;
            key = arr[j];
            while (k > i && arr[k - 1] > key)
            {            
                arr[k] = arr[k - 1];
                --k;
 
            }
            arr[k] = key;
            ++j;
        }
        ++i;
    }
}
void mergeSort(int *arr, int start, int end)
 {
    if(start < end)
    {
        int mid = (end + start) / 2;
        mergeSort(arr, start, mid);
        mergeSort(arr, mid + 1, end);
        merge(arr, start, mid + 1,end);
        print(arr, start, end);
    }
 }

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值