算法基础(二):排序

归并排序(Merge Sort)

1 基本思想
分治 对半分
解决 对子问题递归排序
合并 将排好的字问题合并
2 分析
平均时间复杂度:O(nlogn)
最佳时间复杂度:O(nlogn)
最差时间复杂度:O(nlogn)
空间复杂度:O(n)
内存占用:Out-place
(注:In-place 表示就地操作,不需要占用额外的空间)
稳定性:稳定

3 代码实现

// 归并排序(C++-递归版)
template<typename T>
void merge_sort_recursive(T arr[], T reg[], int start, int end) {
    if (start >= end)
        return;
    int len = end - start, mid = (len >> 1) + start;
    int start1 = start, end1 = mid;
    int start2 = mid + 1, end2 = end;
    merge_sort_recursive(arr, reg, start1, end1);
    merge_sort_recursive(arr, reg, start2, end2);
    int k = start;
    while (start1 <= end1 && start2 <= end2)
        reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
    while (start1 <= end1)
        reg[k++] = arr[start1++];
    while (start2 <= end2)
        reg[k++] = arr[start2++];
    for (k = start; k <= end; k++)
        arr[k] = reg[k];
}

// merge_sort
template<typename T>
void merge_sort(T arr[], const int len) {
    T reg[len];
    merge_sort_recursive(arr, reg, 0, len - 1);
}

快速排序(Quick Sort)

1 基本思想
用分治法(Divide and conquer)
选基准
重排数列,较小的数放在基准前,较大的数放在基准后
递归对子问题排序
2 复杂度
平均时间复杂度:O(NlogN)
最佳时间复杂度:O(NlogN)
最差时间复杂度:O(N^2)(退化为冒泡排序)
最优时间复杂度:O(logN)
最差时间复杂度:O(N)
内存占用:In-Place
稳定性: 不稳定
3 代码实现

#include<stdio.h>
 
// 打印数组
 void print_array(int *array, int length)
 {
     int index = 0;
     printf("array:\n");
     for(; index < length; index++){
         printf(" %d,", *(array+index));
     }   
     printf("\n\n");
 }
 
 void quickSort(int array[], int length)
 {
     int start = 0;
     int end = length-1;
     int value = array[start];// 得到哨兵元素
 
     if (1 > length) return;// 递归出口
 
     while(start < end){// 以哨兵元素为标准,分成大于它和小于它的两列元素
 
         while(start < end){// 从数组尾部往前循环得到小于哨兵元素的一个元素
             if ( array[end--] < value ){
                 array[start++] = array[++end];
                 break;
             }   
         }   
 
         while( start < end ){// 从数组头部往后循环得到大于哨兵元素的一个元素
             if( array[start++] > value){
                 array[end--] = array[--start];
                 break;
             }   
         }   
     }   
 
     array[start] = value;// 放置哨兵元素
     printf("\nstart:%d, end:%d\n", start, end);// 这个是测试下start和end是否一样
     quickSort(array, start);// 递归排序小于哨兵元素的那一列元素
     quickSort(array + start + 1, length - start - 1);// 递归排序大于哨兵元素的那一列
 }
 
 
 int main(void)
 {
     int array[12] = {1,11,12,4,2,6,9,0,3,7,8,2};
     print_array(array, 12);// 开始前打印下
     quickSort(array, 12);// 快速排序
     print_array(array, 12);// 排序后打印下
     return 0;
 }

4 适用数据不大的情况
5 改进:随机选择,而不选择第一个数,从概率上讲,不会退化到冒泡排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值