• 基本的排序算法C++实现(插入排序,选择排序,冒泡排序,归并排序,快速排序,最大堆排序,希尔排序)


    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~
    http://www.cnblogs.com/chenxiwenruo/p/8529525.html
    特别不喜欢那些随便转载别人的原创文章又不给出链接的
    所以不准偷偷复制博主的博客噢~~

    最近适当复习了下基本的排序算法,虽然做题的时候一般都直接用sort了事,但基本的排序原理还是要了解的,所以把常见的排序又重新写了下。

    基本的插入、选择、冒泡就不说了,归并排序、快速排序可以网上搜算法导论的学习,也很简单。

    1.插入排序

    void insertSort(int a[],int len){
        for(int i=1;i<len;i++){
            int tmp=a[i];
            int j=i-1;
            while(j>=0 && tmp<a[j]){
                a[j+1]=a[j];
                j--;
            }
            a[j+1]=tmp;
        }
    }
    View Code

    2.选择排序

    void selectSort(int a[],int len){
        for(int i=0;i<len-1;i++){
            int minidx=i;
            for(int j=i+1;j<len;j++){
                if(a[j]<a[minidx]){
                    minidx=j;
                }
            }
            if(a[i]>a[minidx]){
                int tmp=a[i];
                a[i]=a[minidx];
                a[minidx]=tmp;
            }
        }
    }
    View Code

    3.冒泡排序

    void bubbleSort(int a[],int len){
        int tmp;
        for(int i=0;i<len-1;i++){
            bool flag=true;
            for(int j=0;j<len-i-1;j++){
                if(a[j]>a[j+1]){
                    tmp=a[j+1];
                    a[j+1]=a[j];
                    a[j]=tmp;
                    flag=false;
                }
            }
            if(flag)
                break;
        }
    }
    View Code

    4.归并排序O(NlgN)

    #define INF 0x3f3f3f3f
    /*
    将[l,mid]和[mid+1,r]两个区间进行合并,每次取两个开头最小的那个
    */
    void merges(int a[],int l,int mid,int r){
        int len1=mid-l+1;
        int len2=r-mid;
        int L[len1+1],R[len2+1];
        for(int i=0;i<len1;i++)
            L[i]=a[l+i];
        for(int i=0;i<len2;i++)
            R[i]=a[mid+1+i];
        L[len1]=INF;
        R[len2]=INF;
        int left=0,right=0;
        for(int k=l;k<=r;k++){
            if(L[left]<=R[right]){
                a[k]=L[left];
                left++;
            }
            else{
                a[k]=R[right];
                right++;
            }
        }
    }
    //对区间[l,r]进行归并排序
    void mergeSort(int a[],int l,int r){
        if(l<r){
            int mid=(r+l)/2;
            mergeSort(a,l,mid);
            mergeSort(a,mid+1,r);
            merges(a,l,mid,r);
        }
    }
    View Code

    5.快速排序O(NlgN)

    /*
    以最后a[r]为划分点,将数组a划分成两个部分
    前部分<=a[r],后部分>a[r]
    最后返回a[r]的索引
    */
    int quick_partition(int a[],int l,int r){
        int x=a[r];
        int i=l-1;
        for(int j=l;j<r;j++){
            if(a[j]<=x){
                i++;
                swap(a[i],a[j]);
            }
        }
        swap(a[i+1],a[r]);
        return i+1;
    
    }
    void quickSort(int a[],int l,int r){
        if(l<r){
            int mid=quick_partition(a,l,r);
            quickSort(a,l,mid-1);
            quickSort(a,mid+1,r);
        }
    }
    View Code

    6.最大堆排序O(NlgN)

    //----------------堆排序O(NlgN)最大堆的实现--------------------------
    /*
    将最大堆的根节点和末尾交换后,可能破坏了最大堆的性质,所以要进行更新
    */
    void heap_update(int a[],int i,int heap_size){
        int l=i*2+1;
        int r=i*2+2;
        int large=i;
        if(l<heap_size && a[l]>a[large])
            large=l;
        if(r<heap_size && a[r]>a[large])
            large=r;
        if(large!=i){
            swap(a[i],a[large]);
            heap_update(a,large,heap_size);
        }
    }
    /*
    将val插入到数组a的末尾,并进行最大堆的维护
    */
    void heap_insert(int a[],int val,int heap_size){
        heap_size++;
        a[heap_size-1]=val;
        int idx=heap_size-1;
        while(idx>0 && a[idx/2]<a[idx]){
            swap(a[idx/2],a[idx]);
            idx=idx>>1;
        }
    }
    void heapSort(int a[],int len){
        //构建最大堆
        for(int i=0;i<len;i++)
            heap_insert(a,a[i],i);
        for(int i=len-1;i>=0;i--){
            swap(a[0],a[i]);
            heap_update(a,0,i);  //每次heap_size减小1的
        }
    }
    View Code

    7.希尔排序

    最近突然遇到希尔排序,之前没听过,所以就了解一下,不专门写介绍了,给一篇链接吧,讲得挺详细的

    https://www.cnblogs.com/chengxiao/p/6104371.html

    希尔排序对于增量序列(即gap)的选择很重要,会影响到排序的性能,通常都采用gap=length/2。

    希尔排序是可以突破O(N^2)的,但gap/=2的情况下最坏时间复杂度依然为O(N^2),一些优化过后的序列最坏情况可以到O(N^3/2)。

    /*
    https://www.cnblogs.com/chengxiao/p/6104371.html
    希尔排序
    */
    void shellsort(int a[],int len){
        //划分成gap个组
        for(int gap=len/2;gap>0;gap/=2){
            //从第gap个元素,逐个对其所在组进行插入排序操作
            //而不需要for每个组进行操作
            for(int i=gap;i<len;i++){
                int j=i-gap;
                //插入排序采用交换法即可
                while(j>=0 && a[j]>a[j+gap]){
                    swap(a[j],a[j+gap]);
                    j-=gap;
                }
            }
            /*
            printf("gap:%d
    ",gap);
            for(int i=0;i<len;i++)
                printf("%d ",a[i]);
            printf("
    ");
            */
        }
    }
    View Code

    完整的测试代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    //----------------插入排序--------------------------
    void insertSort(int a[],int len){
        for(int i=1;i<len;i++){
            int tmp=a[i];
            int j=i-1;
            while(j>=0 && tmp<a[j]){
                a[j+1]=a[j];
                j--;
            }
            a[j+1]=tmp;
        }
    }
    //----------------选择排序--------------------------
    void selectSort(int a[],int len){
        for(int i=0;i<len-1;i++){
            int minidx=i;
            for(int j=i+1;j<len;j++){
                if(a[j]<a[minidx]){
                    minidx=j;
                }
            }
            if(a[i]>a[minidx]){
                int tmp=a[i];
                a[i]=a[minidx];
                a[minidx]=tmp;
            }
        }
    }
    //----------------冒泡排序--------------------------
    void bubbleSort(int a[],int len){
        int tmp;
        for(int i=0;i<len-1;i++){
            bool flag=true;
            for(int j=0;j<len-i-1;j++){
                if(a[j]>a[j+1]){
                    tmp=a[j+1];
                    a[j+1]=a[j];
                    a[j]=tmp;
                    flag=false;
                }
            }
            if(flag)
                break;
        }
    }
    //----------------归并排序O(NlgN)--------------------------
    #define INF 0x3f3f3f3f
    /*
    将[l,mid]和[mid+1,r]两个区间进行合并,每次取两个开头最小的那个
    */
    void merges(int a[],int l,int mid,int r){
        int len1=mid-l+1;
        int len2=r-mid;
        int L[len1+1],R[len2+1];
        for(int i=0;i<len1;i++)
            L[i]=a[l+i];
        for(int i=0;i<len2;i++)
            R[i]=a[mid+1+i];
        L[len1]=INF;
        R[len2]=INF;
        int left=0,right=0;
        for(int k=l;k<=r;k++){
            if(L[left]<=R[right]){
                a[k]=L[left];
                left++;
            }
            else{
                a[k]=R[right];
                right++;
            }
        }
    }
    //对区间[l,r]进行归并排序
    void mergeSort(int a[],int l,int r){
        if(l<r){
            int mid=(r+l)/2;
            mergeSort(a,l,mid);
            mergeSort(a,mid+1,r);
            merges(a,l,mid,r);
        }
    }
    //----------------快速排序O(NlgN)--------------------------
    /*
    以最后a[r]为划分点,将数组a划分成两个部分
    前部分<=a[r],后部分>a[r]
    最后返回a[r]的索引
    */
    int quick_partition(int a[],int l,int r){
        int x=a[r];
        int i=l-1;
        for(int j=l;j<r;j++){
            if(a[j]<=x){
                i++;
                swap(a[i],a[j]);
            }
        }
        swap(a[i+1],a[r]);
        return i+1;
    
    }
    void quickSort(int a[],int l,int r){
        if(l<r){
            int mid=quick_partition(a,l,r);
            quickSort(a,l,mid-1);
            quickSort(a,mid+1,r);
        }
    }
    
    
    int main()
    {
        int num=10;
        int a[num];
        srand((unsigned)time(NULL));
        for(int i=0;i<num;i++){
            a[i]=rand()%20;
            printf("%d ",a[i]);
        }
        printf("
    ");
        quickSort(a,0,num-1);
        for(int i=0;i<num;i++){
            printf("%d ",a[i]);
        }
        return 0;
    }
    View Code

    最后,当然排序最省力的就是C++中的自定义排序了,直接用algorithm中的sort即可。

    #include <algorithm>
    bool cmp(int a,int b){
        return a>b; 
    }
    
    sort(a,a+n); //a为数组,n为数组的长度,默认是从小到大排序
    sort(a,a+n,cmp);//cmp即为自定义比较函数,此处是从大到小排序。
  • 相关阅读:
    MySql使用游标Cursor循环(While)更新数据
    初试TinyIoCContainer笔记
    用Razor做静态页面生成器
    在CentOS6.5上安装MariaDB
    mono的远程调试
    mono3.2.3+Jexus5.5+openSuSE13.1的asp.net
    mono3.2和monodevelop4.0在ubuntu12.04上两天的苦战
    第一节知识点:.net与c#的概念
    支付宝支付功能(使用支付宝sdk)
    vs2017/vs2019 去掉 单击aspx文件预览页面
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/8529525.html
Copyright © 2020-2023  润新知