重温常见排序法

1、冒泡排序法

算法简单,以 长度为 len-1 的arr 数组  为例:
1、从 0到 len-1 依次比较相邻位置的数,后者大于前者,交换位置
     一轮过后,最后一个位置确定,是最大数。
2、第i轮只需比较 0 到 len-1-i 即可。
     直到最后一轮结束,数组排序就完成了。
/* 冒泡排序 */
void bubble_sort(int *arr,int len) {
   for (int i = 0; i < len; i++){
        for (int j = 0; j < len-1-i; j++){
            if (arr[j]>arr[j+1]){
                arr[j]   = arr[j] + arr[+ 1];
                arr[j+1] = arr[j] - arr[+ 1];
                arr[j]   = arr[j] - arr[+ 1];
                printArr(arr, len);
            }
        }
   }}
2、选择排序法

和冒泡法步骤差不多。以 长度为 len的arr数组为例:
第一轮:将 arr[1]-arr[len-1] 依次和 arr[0] 比较,小于arr[0]则交换。
第 i 轮:将 arr[i+1]-arr[len-1]一次和arr[0] 比较,小于arr[i]则交换
/* 选择排序 */
void select_sort(int *arr, int len) {
     for (int i = 0; i < len - 1; i++) {
          for (int j = i+1; j < len; j++) {
               if (arr[i] > arr[j]) {
                    arr[i] = arr[i] + arr[j];
                    arr[j] = arr[i] - arr[j];
                    arr[i] = arr[i] - arr[j];
                    print(arr, len);
               }
          }
     }}
3、插入排序法

又分为直接插入排序法和二分插入排序法
直接插入排序
/* 直接插入排序 */
void insert_sort(int *arr, int len) {
   for (int i = 1; i < len; i++){//以第一个数作为有序数组,其余为无序数组
       for (int j = i; j > 0 && arr[j-1]>arr[j]; j--){
            arr[j]   = arr[j] + arr[- 1]; //交换arr[j]和arr[j-1];
            arr[j-1] = arr[j] - arr[- 1];
            arr[j]   = arr[j] - arr[- 1];
        }
   }}
插入排序百度上讲的太抽象
第2个数和第1个比,小于第1个数,则交换之
第3个数和第2个比,小于则交换,第2个在和第1个比
...
第N个数和第N-1个比,小于则交行,...第2个和第1个


二分插入排序
/* 二分插入排序 */
void binary_insert_sort ( int * arr ,  int len )  {
    for  ( int i  =  1 ; i  < len ; i + + ) {    //以第一个数为已排序数组
        int l  =  0 , h  = i  -  1 ;      //有序数组0~i-1
        int p  =  (+ h )  /  2 ;      //中间数位置
        while  (< = h )  {          //二分查找
            if  (arr [p ]  > arr [i ] ) h  = p  -  1 ;    //左边
            else l  = p  +  1 ;      //有吧
            p  =  (+ h )  /  2 ;  //重设中间点
        }
        for  ( int j  = i ; j  > l ; j - - ) { //插入点在l前
            arr [j ]    = arr [j ]  + arr [-  1 ] ;
            arr [j - 1 ]  = arr [j ]  - arr [-  1 ] ;
            arr [j ]    = arr [j ]  - arr [-  1 ] ;
        }
    } }
4、希尔排序
希尔排序是直接插入排序的一种改进。
1、选择一个小于数组长度的增量 d 1,我们选得 d 1=len/2,对于0,0+ d 1,0+2d 1,...构成有一个数组
2、我们将其视为一个数组进行直接插入排序
3、然后再设置 d 2, d 2< d 1,这里选择的 d 2= d 1/2重复第2步
4、直到d n-1= 1, d n< d n-1,这时,分组变成一个
5、排序完成
/* 希尔排序 */
void shell_sort(int *arr,int len) {
   int d = len / 2; //起始增量,为1,就是直接插入排序
   while (d>=1){
        for (int i = 0; i < d; i++) {
            cout << "-----------------------" << endl;
            int j = i + d;
            while (< len) {
                for (int k = j; k > 0 && arr[- d]>arr[k]; k -= d) {
                    arr[k]     = arr[k] + arr[- d]; //交换arr[j]和arr[j-1];
                    arr[- d] = arr[k] - arr[- d];
                    arr[k]     = arr[k] - arr[- d];
                    printArr(arr, len);
                }
                j += d;
            }
        }
        d=(== 1) ? 0 : d / 2;
   }}


5、快速排序法

基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以 递归 进行,以此达到整个数据变成有序序列。

1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数

快速排序又被称为分治法,确切的说是:挖坑填数+分治法
/* 快速排序 */
void quick_sort ( int  *arr , int _l , int _h )  {
        if (_>= _h) return; //判断结束
        int l  = _l , h  = _h ;    //保存范围
        int pivot  = arr [_l ] ; //设置基准
        while  (l <h ) {
                while  ( (< h )  & & arr [h ]  > pivot ) h - - ; //右向左,找首个小于pivot的数,h指向它
                arr [l ]  = arr [h ] ;
                while  ( (< h )  & & arr [l ]  < pivot ) l + + ; //左向右,找首个大于pivot的数,l指向它
                arr [h ]  = arr [l ] ;
        }
        arr [l ]  = pivot ;              //重设基准
        quick_sort (arr , _l , l  -  1 ) ; //分区递归
        quick_sort (arr , l  +  1 , _h ) ;
}

 

6、归并排序
归并排序的思想是将两个有序数组合并成一个数组,合并后仍然有序
这就分成了两部分,一部分是有序数组的合并,一部分是分组递归
/*归并排序*/
void merge_array ( int  *a ,  int f ,  int t ,  int m ,  int  *r )  {
        int i , j , k ;
        i  = f ;
        k  =  0 ;
        j  = m  +  1 ;
        //a数组中,f~m一个数组,m+1~t是一个数组,将其合并到r中
        while  (< = m & &< = t )  {
                if  (a [i ]  < a [j ] )
                        r [k + + ]  = a [i + + ] ;
                else
                        r [k + + ]  = a [j + + ] ;
        }
        while  (< = m )
                r [k + + ]  = a [i + + ] ;
        while  (< = t )
                r [k + + ]  = a [j + + ] ;
        for  ( int i  =  0 ; i  < = t  - f ; i + + ) {
                a [+ i ]  = r [i ] ;
                cout  < <  " a[ "  < < f  + i  < <  " ]= "  < < a [+ i ]  < <  endl ;
        }
}

void merge_sort ( int  *arr ,  int l ,  int h ,  int m ,  int  *r )  {
        if  (l <h ) {
                merge_sort (arr , l , m ,  (+ m )  /  2 , r ) ;
                merge_sort (arr , m + 1 , h ,  (m + 1  + h )  /  2 , r ) ;
                merge_array (arr ,l ,h , (l +h ) / 2 ,r ) ;
        }
}
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值