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


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

    一.冒泡排序

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

    举个例子:现有数组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);//分出来的右子数组
        }
    }
  • 相关阅读:
    docker学习1--dockerfile
    关于java php go 中AES加解密秘钥长度问题
    API设计中响应数据格式用json的优点
    mac air中编译安装swoole
    跟踪填写表单重复信息
    JS简单实现点赞操作
    JS验证码生成(入门级别)
    注册页面(入门)
    登录表单(入门简单)
    简单的UDP编程1
  • 原文地址:https://www.cnblogs.com/51selfstudy/p/10528914.html
Copyright © 2020-2023  润新知