十大排序算法详细集合

排序算法大集合


源代码如下

类的定义


    #pragma once
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Sort {
    public:
    /*
    *选择排序:首先找到数组中最小的数,其次,将他和数组中的第一个元素交换位置
    *
    *再次,在剩下的元素中找到最小的元素,将他与数组中的第二个元素交换位置。如此往复。
    *因此叫做选择排序。
    *
    *@author qls
    *@date 2018 7-31  下午16:15
    *
    */
    void select_sort(vector<int> & arr);

    /**
    *
    *插入排序:通常人们整理桥牌的方法是一张张的来,将每一张牌插入到其他已经有序的牌
    *的适当位置。在计算机的实现中,这种算法叫做 插入排序
    *
    *@author qls
    *@date 2018 7-31  下午16:31
    *
    **/
    void insert_sort(vector<int> &arr);
    /**
    *希尔排序是一种基于插入排序的快速排序算法。
    *对于大规模乱序数组插入排序很慢,因为他只会交换相邻的元素
    *因此元素只能一点一点的从数组的一端移动到另一端。
    *
    *希尔排序为了加快速度简单的改进插入排序,交换不相邻的元素
    *以对数组的局部进行排序,最终用插入排序将局部有序的数组排序
    ********************************************
    *希尔排序的思想是使数组中任意间隔为h的元素都是有序的。这样的数组
    *称为h有序数组。
    *一个h有序数组就是h个相互独立的有序数组编制在一起形成的一个数组
    *希尔排序需要利用递增序列,这是核心思想。希尔排序的递增序列必须互质。
    *********************************************
    *实现希尔排序的一种方法是对于每个h,用插入排序将h个子数组独立排序。
    *
        *@author qls
    *@date 2018 7-31  下午17:21
    *
    */
    void shell_sort(vector<int> &arr);

    /**
    *归并排序
    *将一个数组递归的分成两半分别排序,然后将结果归并起来
    *归并排序的缺点是是其需要的额外的空间和任意长度的N成正比
    *
    *@author qls
    *@date 2018 8-1  上午午10:35
    */
    void guibin_sort(vector<int> &res);

    /**
    *快速排序是一种分治的排序算法。它将一个数组分成两个子数组
    *将两部分独立的排序。快排和归并排序是互补的:
    *归并排序将数组分成两个子数组分别排序,并将有序的子数组归并并以将整个
    *数组排序;而快速排序将数组排序的方式则是当两个数组都有序
    *时整个数组也就自然有序了。在第一种情况中,递归调用发生在处理整个数组
    *z之前;在第二种情况中,递归调用发生在处理整个数组之后。
    *在归并排序中,一个数组被等分为两半;在快速排序中,切分(partition)
    *的位置取决于数组的内容。
    *
    *
    *@author qls
    *@date 2018 8-1  下午15:35
     */
     void quick_sort(vector<int> &res);

     /**
     *二叉堆是一个数组,其可以被看成一个近似的完全二叉树。
     *二叉堆分为两种情况:最大堆和最小堆。
     *在最大堆中,最大堆性质是指除了根以外的所有节点都满足A[parent]>=A[i]
     *即某个节点的值至多与其父节点一样大。
     *在堆排序算法中一般使用最大堆,而优先队列一般使用最小堆。
     *
     *@author qls
     *@date 2018 8-2  下午16:28 
     **/
     void Heap_sort(vector<int> &res);

     void sort_out(vector<int> &arr);


    private:

    void gb_sort(vector<int> &res,int L,int R); //归并排序接口
    void merge(vector<int> &res,int L,int mid,int R);//归并
    void quicksort(vector<int> &res,int L,int R);//快速排序
    int partition(vector<int> &res,int L,int R);//快排分化
    void max_heap(vector<int> &res,int i,int heap_size); //用于维持最大堆
    void build_heap(vector<int> &res); //创建最大堆
    void Heapsort(vector<int>&res);//堆排序

};

实现如下

        #include "Sort.h"

    void Sort::select_sort(vector<int>& arr)
    {
        for (int i = 0;i < arr.size() - 1;++i) {     

             auto beg=min_element(arr.begin()+i,arr.end());
             swap(arr[i],*beg);
        }
    }

    void Sort::insert_sort(vector<int>& arr)
    {
        for (int i = 1;i < arr.size();++i) {
            int p=i-1; //已经插入的排好序的最大下标
            int temp=arr[i];
            while (p >= 0 && arr[p] > temp) {
                arr[p+1]=arr[p];
                p--;
            }
            arr[p+1]=temp;
        }
    }

    void Sort::shell_sort(vector<int>& arr)
    {
        //升序排列
        int N=arr.size();
        int h=1; //递增序列
        while(h<N/3) h=3*h+1;
        while (h >= 1) {
            //将数组变为h有序
            for (int i = h;i < N;++i) {
                //将arr[i]插入到arr[i-h],arr[i-2h],arr[i-3h].....之中
                for (int j = i;j >= h && (arr[j] < arr[j - h]);j -= h) {
                    swap(arr[j],arr[j-h]);
                }
            }
            h/=3;
        }
    }

    void Sort::guibin_sort(vector<int>& res)
    {
        gb_sort(res,0,res.size()-1);
    }

    void Sort::quick_sort(vector<int>& res)
    {
        quicksort(res,0,res.size()-1);
    }

    void Sort::Heap_sort(vector<int>& res)
    {
        Heapsort(res);
    }

    void Sort::sort_out(vector<int>& arr)
    {
        for (auto &c : arr) {
            cout<<c<<" ";
        }
        cout<<endl;
    }

    void Sort::gb_sort(vector<int>& res, int L, int R)
    {
        if (L < R) {
            int mid=(L+R)/2; //归并
            gb_sort(res,L,mid);
            gb_sort(res,mid+1,R);
            merge(res,L,mid,R);
        }
        return;
    }

    void Sort::merge(vector<int>& res, int L, int mid, int R)
    {
        int left=mid+1-L;
        int right=R-mid;
        vector<int> La(left);
        vector<int> Ra(right); //生成两个辅助数组
        /*
        *将相对应的值复制到指定数组中
        */
        for (int i = 0;i < left;++i) {
            La[i]=res[i+L]; 
        }
        for (int j = 0;j < right;++j) {
            Ra[j]=res[mid+1+j];
        }
        /**
        *归并
        **/
        int i =0,j=0;
        int k=L;
        while (i < left&&j < right) {
            if (La[i] <= Ra[j]) {
                res[k]=La[i];
                ++i;
            }
            else {
                res[k]=Ra[j];
                ++j;
            }
            ++k;
        }
        while (i < left) {

            res[k] = La[i];
            ++i;
            ++k;
        }
        while (j < right) {
            res[k] = Ra[j];
            ++j;
            ++k;
        }
        /*
        for (int k = L;k <= R;++k)
        {
            if (i<left&&j<right&&La[i] <= Ra[j])
            {
                res[k] = La[i];
                ++i;
            }
            else if (j<right&&i<left&&La[i] > Ra[j])
            {

                res[k] = Ra[j];
                ++j;
            }
            else if (i < left)
            {
                res[k] = La[i];
                ++i;
            }
            else if (j< right)
            {
                res[k] = Ra[j];
                ++j;

            }
        }*/
    }

    void Sort::quicksort(vector<int>& res, int L, int R)
    {   
        if (L < R) {
            int p=partition(res,L,R);
            quicksort(res,L,p-1);
            quicksort(res,p+1,R);
        }
    }

    int Sort::partition(vector<int>& res, int L, int R)
    {
        int p=L-1;
        int value=res[R];
        for (int k = L;k <= R;++k) {
            if (res[k] <=value) {
                ++p;
                swap(res[k],res[p]); //将小于value的值,放在前半部分
            }
        }
        swap(res[p+1],res[R]); //交换两个值
        return p+1;

    }

    /** 
    * 维持最大堆的策略叫做 下滤。
    **/
    void Sort::max_heap(vector<int>& res, int i,int heap_size)
    {
        int lastE=res[i];
        int parent=i; //最大堆的根节点
        int child ;
        for (;2 * parent+1 <=heap_size;parent = child) {
            child=2*parent+1;
            if (child != heap_size && res[child + 1] > res[child]) {
                /*由于将每一个节点看做有两个儿子,因此利用child!=res.size(),进行判断
                *res[child + 1] > res[child]此时右儿子比左儿子大
                *选择右儿子
                */
                child++;
            }
            if (lastE >res[child]) {
                break;
            }
            else {
                res[parent] = res[child];
            }
        }
        res[parent]=lastE;
    }

    void Sort::build_heap(vector<int>& res)
    {
        for (int parent = res.size() / 2;parent >= 0;--parent) {
            max_heap(res,parent,res.size()-1);
        }
    }

    /*
    *堆排序首先将输入的数组建成一个最大堆。
    *因为数组中最大值总是在res[0],故通过将其与res[res.size()-1]交换,
    *便可将该元素放到正确的位置。在剩余节点中,原来根的孩子节点仍然是一个
    *最大堆,然而新的根节点可能会违背最大堆的性质。为了维护最大堆的性质,调用max_heap
    *从而将剩下的堆构造成一个最大堆。一直循环直到从n-1降到1.
    *
    *@author qls
    *@2018/8/2 下午17:13

    **/
    void Sort::Heapsort(vector<int>& res)
    {
        build_heap(res);
        for (int i = res.size() - 1;i > 0;--i) {
            swap(res[0],res[i]); //交换两个值
            max_heap(res,0,i-1); //重新构造堆    
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qls315

感觉好可打赏几毛钱增强更新动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值