zoukankan      html  css  js  c++  java
  • 数据结构和算法自学之排序算法(一)

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

    一.冒泡排序

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

    举个例子:现有数组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);//分出来的右子数组
        }
    }
  • 相关阅读:
    Git .gitignore文件简介及使用
    JMeter 报告监听器导入.jtl结果文件报错解决方案
    JMeter 中实现发送Java请求
    JMeter 正则表达式提取器结合ForEach控制器遍历提取变量值
    Tomcat_记一次tomcatwar包应用简单部署过程
    Python_基于Python同Linux进行交互式操作实现通过堡垒机访问目标机
    Python_关于多线程下变量赋值取值的一点研究
    JMeter 后置处理器之正则表达式提取器详解
    性能测试 CentOS下结合InfluxDB及Grafana图表实时展示JMeter相关性能数据
    Python 标准类库-数据类型之copy-深拷贝浅拷贝操作
  • 原文地址:https://www.cnblogs.com/51selfstudy/p/10528914.html
Copyright © 2011-2022 走看看