• C++ 各种排序算法总结


    1. Merge Sort / 归并排序

    /*  Divide and conquer
     *  将一个数组中的两个相邻有序区间合并成一个
     *
     *  参数说明:
     *     A     -- 包含两个有序区间的数组
     *     lo    -- 第1个有序区间的起始地址。
     *     mi    -- 第1个有序区间的结束地址。也是第2个有序区间的起始地址。
     *     hi    -- 第2个有序区间的结束地址。
     */
     1 void merge(int A[],int lo,int hi,int mi){
     2     //以mi为界、各自有序癿子向量[lo, mi)和[mi, hi) 
     3     int temp[hi-lo+1];
     4     int i=lo, j=mi+1, k=0;
     5 
     6     while(i<=mid&&j<=lo){
     7         if(A[i]<=A[j])    
     8             temp[k++]=A[i++];
     9         else            
    10             temp[k++]=A[j++];
    11     }
    12     while(i<=mid)    temp[k++]=A[i++];
    13     while(j<=hi)    temp[k++]=A[j++];
    14 
    15     for(i=0;i<k;i++)     
    16         A[lo++]=temp[i++];
    17 }
    18 
    19 void mergeSort(int lo,int hi){
    20     if(hi-lo < 2)    return;
    21 
    22     int mi=(hi+lo)>>1;
    23     mergeSort(lo,mi);
    24     mergeSort(mi,hi);
    25     merge(lo,hi,mi);
    26 }

    2. Quick Sort /快排

    /*   Divide and conquer
     *
     * - 在R[low,high]中任选一个记录作为基准(Pivot),
     *   以此基准将当前无序区划分为左、右两个较小的子区间R[low,pivotpos-1)和R[pivotpos+1,high],
     *
     * - 并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,此时左标记向右移动,
     *   直到左标记的关键字大于右标记的关键字,这时左标记停下,右标记同理进行操作。
     *   直到左标记和右标记都停下时,分两种情况讨论:
     *     1.左标记与右标记不在同一位置,此时交换左右两标记的关键字
     *     2.左右标记在同一位置,此时交换这一位置关键字和基准的位置
     *
     * - 此后就是分两边情况递归  
     */
     1 void QuickSort(int R[],int low,int high){
     2     int i,j,temp;
     3     i=low;    j=high;
     4     if(low<high){
     5         temp=R[low];
     6         while(i!=j){
     7             while(i<j&&R[j]>=temp)    
     8                 j--;
     9             if(i<j)            
    10                 R[i++]=R[j];
    11 
    12             while(i<j&&R[i]<temp)    
    13                 i++;
    14             if(i<j)            
    15                 R[j--]=R[i];
    16         }
    17         R[i]=temp;
    18         QuickSort(R,low,i-1);
    19         QuickSort(R,i+1,high);
    20     }
    21 }

    3. 冒泡排序

    /*   
     * 借助布尔型标志位sorted,可及时提前退出,而不致蛮力地做n-1趟扫描交换
     * 对尾部有序(或接近有序)的输入,算法依然亦步亦趋地收敛,导致元素比较次数过多 
     */
    void bubblesort1 ( int A[], int n ) { 
        for ( bool sorted = false; sorted = !sorted; n-- ) { 
       //在尚未确认已全局排序之前,逐趟进行扫描交换 for ( int i = 1; i < n; i++ ) {
         //自左向右逐对检查当前范围A[0, n)内的各相邻元素 if ( A[i-1] > A[i] ){ swap ( A[i-1], A[i] ); sorted = false; //因整体排序不能保证,需要清除排序标志 } } } }
     void bubblesort2 ( int A[], int n ) { 
        for ( bool sorted = false; sorted = !sorted; n-- ) { //在尚未确认已全局排序之前,逐趟进行扫描交换
           for ( int i = 1; i < n; i++ ) { //自左向右逐对检查当前范围A[0, n)内的各相邻元素
              if ( A[i-1] > A[i] ) { //一旦A[i-1]与A[i]逆序,则
                 swap ( A[i-1], A[i] ); //交换之,并
                 sorted = false; //因整体排序不能保证,需要清除排序标志
              }
           }
        }
     } 
    /*
     * 借助整数m尽快地收缩待排序区间:既可提前退出,更可减少每趟(及所有)扫描交换中元素比较操作
     * 对尾部有序(或接近有序)的输入,算法收敛的速度大大提高
     * 元素交换的次数仅取决于输入序列,与版本1和版本2相同
     */
     1 void bubblesort3 ( int A[], int n ) { 
     2     for ( int m; 1 < n; n = m ) { //在尚未确认已全局排序之前,逐趟进行扫描交换
     3        for ( int i = m = 1; i < n; i++ ) { //自左向右逐对检查当前范围A[0, m)内的各相邻元素
     4           if ( A[i-1] > A[i] ) { //一旦A[i-1]与A[i]逆序,则
     5              swap ( A[i-1], A[i] ); //交换之,并
     6              m = i; //更新待排序区间的长度
     7           }
     8        }
     9     }
    10  } 
  • 相关阅读:
    代码中引用res里的颜色、图片
    time.setToNow() 取当前时间,月份有误
    adb报错:The connection to adb is down, and a severe&nbs
    安卓下拉刷新、上拉加载数据显示
    4、安卓数据存储——sqlite
    3、安卓数据存储——缓存、内存管理
    2、安卓数据存储——本地文件
    1、安卓数据存储机制——sharedPreference
    一个异步任务接收两个url下载两个图片
    adb报错:The connection to adb is down, and a severe&nbs
  • 原文地址:https://www.cnblogs.com/jaszzz/p/12634468.html
Copyright © 2020-2023  润新知