zoukankan      html  css  js  c++  java
  • 算法笔记-冒泡排序、插入排序、选择排序

    冒泡排序、插入排序、选择排序、归并排序、快速排序、计数排序、基数排序、桶排序。
     
    对于排序算法执行效率的分析,我们一般会从这几个方面来衡量:
    1. 最好情况、最坏情况、平均情况时间复杂度
    2. 时间复杂度的系数、常数 、低阶
    3. 比较次数和交换(或移动)次数
     
    冒泡排序(Bubble Sort)
    冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。
     
    Q:第一,冒泡排序是原地排序算法吗?
    A:冒泡的过程只涉及相邻数据的交换操作,只需要常量级的临时空间,所以它的空间复杂度为O(1),是一个原地排序算法。
    Q:第二,冒泡排序是稳定的排序算法吗?
    A:在冒泡排序中,只有交换才可以改变两个元素的前后顺序。为了保证冒泡排序算法的稳定性,当有相邻的两个元素大小相等的时候,我们不做交换,相同大小的数据在排序前后不会改变顺序,所以冒泡排序是稳定的排序算法。
    Q:第三,冒泡排序的时间复杂度是多少?
    最好情况下,要排序的数据已经是有序的了,我们只需要进行一次冒泡操作,就可以结束了,所以最好情况时间复杂度是 O(n)。而最坏的情况是,要排序的数据刚好是倒序排列的,我们需要进行 n 次冒泡操作,所以最坏情况时间复杂度为 O(n²)。
    插入排序(Insertion Sort)
    我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。
     
     
    选择排序(Selection Sort)
    选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。
     
    选择排序空间复杂度为 O(1),是一种原地排序算法。选择排序的最好情况时间复杂度、最坏情况和平均情况时间复杂度都为O(n²)。选择排序是一种不稳定的排序算法。
     
    冒泡排序和插入排序的时间复杂度都是 O(n²),都是原地排序算法,为什么插入排序要比冒泡排序更受欢迎呢?从代码实现上来看,冒泡排序的数据交换要比插入排序的数据移动要复杂,冒泡排序需要3 个赋值操作,而插入排序只需要 1 个。
     
     
    <?php
    
    //冒泡排序
    function bubbleSort(&$arr)
    {
        $temp = 0;
        for ($i = 0; $i < count($arr) - 1; $i++) {
            for ($j = 0; $j < count($arr) - 1 - $i; $j++) {
                if ($arr[$j] > $arr[$j + 1]) {
                    $temp = $arr[$j];
                    $arr[$j] = $arr[$j + 1];
                    $arr[$j + 1] = $temp;
                }
            }
        }
    }
    
    //插入排序
    function insertSort(&$arr)
    {
        //先默认下标为0 这个数已经是有序
        for ($i = 1; $i < count($arr); $i++) {
            //$insertVal是准备插入的数
            $insertVal = $arr[$i];
    
            //准备先和$insertIndex比较
            $insertIndex = $i - 1;
    
            //如果这个条件满足,说明,我们还没有找到适当的位置
            while ($insertIndex >= 0 && $insertVal < $arr[$insertIndex]) {
    
                //同时把数后移
                $arr[$insertIndex + 1] = $arr[$insertIndex];
                $insertIndex--;
            }
    
            //插入(这时就给$insertVal找到适当位置)
            $arr[$insertIndex + 1] = $insertVal;
        }
    }
    
    //选择排序
    function selectSort(&$arr)
    {
        $temp = 0;
        for ($i = 0; $i < count($arr) - 1; $i++) {
            //假设 $i就是最小的数
            $minVal = $arr[$i];
            //记录我认为的最小数的下标
            $minIndex = $i;
            for ($j = $i + 1; $j < count($arr); $j++) {
                //说明我们认为的最小值,不是最小值
                if ($minVal > $arr[$j]) {
                    $minVal = $arr[$j];
                    $minIndex = $j;
                }
            }
    
            //最后交换
            $temp = $arr[$i];
            $arr[$i] = $arr[$minIndex];
            $arr[$minIndex] = $temp;
        }
    }
    
    
    $arr1 = $arr2 = $arr3 = [1, 4, 6, 2, 3, 5, 4];
    
    bubbleSort($arr1);
    print_r($arr1);
    
    insertSort($arr2);
    print_r($arr2);
    
    selectSort($arr3);
    print_r($arr3);
  • 相关阅读:
    [CodeForces]Codeforces Round #429 (Div. 2) ABC(待补)
    About Me
    2018-06-14
    Codeforces Codeforces Round #484 (Div. 2) E. Billiard
    Codeforces Codeforces Round #484 (Div. 2) D. Shark
    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
    Codeforces Avito Code Challenge 2018 D. Bookshelves
    Codeforces Round #485 (Div. 2) D. Fair
    Codeforces Round #485 (Div. 2) F. AND Graph
  • 原文地址:https://www.cnblogs.com/rxbook/p/10342492.html
Copyright © 2011-2022 走看看