数据结构和算法自学之排序算法(一)

排序算法可以说是最基本的算法,希望通过自己再写一遍加强记忆。

一.冒泡排序

首先说下冒泡排序,因为排序过程很像气泡从水底一颗一颗冒出来,形象生动的叫冒泡排序,主要过程就是从头开始检索,一一比较,将比较的两者最大的放在后面,循环完毕排序结束。

举个例子:现有数组2,3,7,1,5,那么冒泡排序过程为:

第一轮:2<3,不变,现在数组为2,3,7,1,5

第二轮:3<7,不变,数组为2,3,7,1,5

第三轮:7>1,互换,数组为2,3,1,7,5

第四轮:7<5,互换,数组为2,3,1,5,7

一轮过后,最大值被换到了最后,然后循环n次(数组长度),排序完成,代码如下:

void BubbleSort(int arr[],int len) {
    int i, j = 0;
    int change = 0;                            
    for (i = 0; i < len;++i) {            //外面这层循环用来将整个数组全部从小到大排序
        for (j = 0; j < len - i - 1;++j) {    //里面这层循环将最大值放到最后
            if (arr[j]>arr[j+1]) {
                change = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = change;
            }
        }
    }
}

冒泡法还有着一种可以优化的版本,如果内循环一轮下来,没有任何交换出现,证明后面已经排序完成,可以直接跳出循环,所以在这里添加一个标志符号,代码如下:

void BubbleSort(int arr[], int len) {
    int i, j = 0;
    int change = 0;
    bool flag = true;                        //表示排序还没有完成
    while (flag) {
        for (i = 0; i < len; ++i) {       //外面这层循环用来将整个数组全部从小到大排序
            if (!flag) break;
            flag = false;
            for (j = 0; j < len - i - 1; ++j) {    //里面这层循环将最大值放到最后
                if (arr[j] > arr[j + 1]) {
                    flag = true;     //只要有交换就让外循环继续下去,否则就表明排序完成
                    change = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = change;
                }
            }
        }
    }
}

二.快速排序

这个是用得最多的排序,因为平均效果表现最好,所以面试问到的几率会大很多,主要原理是,在一组数中随机选择一个数,将比这个数小的放在左边,将比这个数大的放在右边,然后再把子数组递归的采用同样的原理分组,直到不能分为止,一般我们就选第一个数作为初始基准,下面以6,1,2,7,9,3,4,5,10,8为例子,

第一轮:以6为基准,7与5交换,6,1,2,5,9,3,4,7,10,8

第二轮:以6为基准,9与4交换,6,1,2,5,4,3,9,7,10,8

第三轮:以6为基准,9位置比3位置后,这时后面已经分为两个子数组,且前面小于6,后面大于6,6与3交换,3,1,2,5,4,6,9,7,10,8

第四轮:前后两个子数组分别重复前三轮步骤

下面代码选自数据结构书上给的参考:

int pa(int arr[], int low,int high) {
    int pivit = arr[low];    //基准点
    while (low<high) {      
        while (low < high&&arr[high] >= pivit) {//从后往前检索,找到比基准点小的值,交换
            --high;
        }
        arr[low] = arr[high];
        while (low < high&&arr[low] <= pivit) {//从前往后检索,找到比基准点大的值,交换
            ++low;
        }
        arr[high] = arr[low];
    }
    arr[low] = pivit;//将基准点移到分割处
    return low;
}

void QuickSort(int arr[],int low,int high) {
    if (low<high) {
        int pivit = pa(arr, low, high);
        QuickSort(arr, low, pivit - 1);//分出来的左子数组
        QuickSort(arr, pivit + 1, high);//分出来的右子数组
    }
}
posted @ 2019-03-14 11:05  薛定谔的哈士奇  阅读(144)  评论(0编辑  收藏  举报