• 算法学习(一) -- 基本算法


    ## 1.插入排序

    插入排序法的基本思路:同样以案例来说明,还是以$arr = array(2,6,3,9),由大到小排序。

    实现原理:插入排序的思想有点像打扑克抓牌的时候,我们插入扑克牌的做法。想象一下,抓牌时,我们都是把抓到的牌按顺序放在手中。因此每抓一张新牌,我们都将其插入到已有的排好序的手牌当中,注意体会刚才的那句话。也就是说,插入排序的思想是,将新来的元素按顺序放入一个已有的有序序列当中。

    代码规律分析:
    array(23,34,12,56,43,98,89)
    注意下面括号中元素插入的位置,和比较的方法
    23,(34)  ,12,56,43,98,89  第一次大循环:$[1]与$[0]比;
    (12),23,34  ,56,43,98,89  第二次大循环:$[2]与$[1]比,$[1]与$[0]比;
    12,23,34,(56)  ,43,98,89  第三次大循环:$[3]与$[2]比,$[2]与$[1]比,$[1]与$[0]比;
    12,23,34,(43),56  ,98,89  ...
    12,23,34,43,56,(98)  ,89  ...
    12,23,34,43,56,(89),98  ...

    ```
    <?php
        $arr = Array(23,34,12,56,43,98,89);
        public function charu($arr){
            //第一层,从第二个元素开始,一共进行n-1次循环
            for($i=1;$i<count($arr);$i++){
                //第二层,将第i个元素插入到左侧相应的位置
                for($j=$i;$j>0;$j--){
                    //从第i个元素开始,与左侧元素依次比较,最小元素不断左移,直到结束
                    if($arr[$j]<$arr[$j-1]){
                        //满足条件,两个元素交换位置
                        $insertVal = $arr[$j];
                        $arr[$j] = $arr[$j-1];
                        $arr[$j-1] = $insertVal;
                    }
                }
            }
            return $arr;
        }
    ```

    ## 2.选择排序

    在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

    代码规律分析:
    array(23,34,12,56,43,98,89)

    (12)  ,34,[23],56,43,98,89  第一次大循环:选出12放在第一位置;将23放在12原位置
    12,([23])  ,34,56,43,98,89  第二次大循环:选出23放在第二位置;恰好自身也在此位置
    12,23,([34])  ,56,43,98,89  第三次大循环:选出34放在第二位置;恰好自身也在此位置
    12,23,34,(43),  [56],98,89  第四次大循环:选出43放在第二位置;将56放在43原位置
    12,23,34,43,([56])  ,98,89  ...
    12,23,34,43,56,(89)  ,[98]  ...
    12,23,34,43,56,89,([98])    ...

    ```
    <?php
        $arr = Array(23,34,12,56,43,98,89);
        public function xuanze($arr){
            //定义进行交换的变量
            $temp=0;
            for($i=0;$i<count($arr)-1;$i++){
                //假设$i就是最小值
                $valmin=$arr[$i];
                //记录最小值的下标
                $minkey=$i;
                for($j=$i+1;$j<count($arr);$j++){
                    //最小值大于后面的数就进行交换,并且记录下相应的下标
                    if($valmin>$arr[$j]){
                        $valmin=$arr[$j];
                        $minkey=$j;
                    }
                }
                //将第i个元素和最小元素进行位置交换
                $temp=$arr[$i];
                $arr[$i]=$arr[$minkey];
                $arr[$minkey]=$temp;
            }
            return $arr;
        }
    ```

    ## 3.冒泡排序

    冒泡排序的思想很简单,就是以此比较相邻的元素大小,将小的前移,大的后移,就像水中的气泡一样,最小的元素经过几次移动,会最终浮到水面上。

    代码规律分析:
    array(23,34,12,56,43,98,89)

    23,34,12,56,43,[89,98]  第一次小循环:89和98比较,交换位置
    23,34,12,56,[43,89],98  第二次小循环:43和89比较,不用换位置
    23,34,12,[43,56],89,98  第三次小循环:56和43比较,交换位置
    23,34,[12,43],56,89,98  ...
    23,[12,34],43,56,89,98  ...
    [12,23],34,43,56,89,98  ...

    至此第一次大循环结束,做小的元素已经移到做左侧,按照同样原理进行第二次大循环.就像上面的列子,不用完整的循环n-1次,所以我们可以引入flag标记,进行优化.
    ```
    <?php
        $arr = Array(23,34,12,56,43,98,89);
        public function maopao($arr)
        {
            $count = count($arr);
            //第一层循环开始
            for($i=1; $i<$count; $i++)
            {
                //本趟排序开始前,交换标志应为假
                $flag = false;    
                //第二层循环,使右侧最小的元素移到最左侧
                for($j=$count-1;$j>=$i;$j--)
                {
                    if($arr[$j]<$arr[$j-1])//交换记录
                    {//如果是从大到小的话,只要在这里的判断改成if($arr[$j]>$arr[$j-1])就可以了
                        $x=$arr[$j];
                        $arr[$j]=$arr[$j-1];
                        $arr[$j-1]=$x;
                        //发生了交换,故将交换标志置为真
                        $flag = true;
                    }
                }
                //本趟排序未发生交换,提前终止算法
                if(! $flag)
                    return $arr;
            }
        }
    ```

    ## 4.快速排序

    所谓快速排序,就是在$arr数组中任意取一个值作为中间值,然后将这个值与数组内其他所有元素相比较,比这个值小的放到左边,比这个值大的放到这个值的右边, 此时完成一趟排序.以此类推,再将这个值左边的数进行上述排序,同样对右边的数进行上述排序.直到将所有的值都比较完.

    首先使用快速排序的理念就需要使用递归,说到递归,就是用函数自己调用自己,逐层深入,最后将拿到的值返回的思想.
    下面我们来看,首先我们需要自定义一个函数quick(),让此函数自己调用自己.
    这里中间值我们用$arr[0],这个是随意取的,不是必须的,
    为了让大家思路清晰,我们先定义两个空数组,就相当于两个杯子,
    让$arr[0]与数组内所有的值进行比较,比$arr[0]小的值放到第一个杯子中,比$arr[0]大的放到第二个杯子中,在程序中分别为$left和$right,
    我们判断,如果给定的数组元素只有一个或为空,此数组将被quick函数返回,不再执行下面的内容,
    接下来我们对数组进行遍历,并用遍历出来的值分别与$arr[0]进行比较,比$arr[0]小的值存入$left数组,比$arr[0]大的的值存入$right数组,此时完成一趟排序,
    接下来再对$left数组和$right数组进行同样的操作,也就是调用函数自己,将$left数组和$right数组传入,直到$left数组或$right数组的数组元素为一个时,不再调用自己,直接返回,
    最后将左边的数组,$arr[0],$right数组合并,即可得到最终的排序结果.


    ```
    <?php
        $arr = Array(23,34,12,56,43,98,89);
        public function kuaisu($arr){
            $left = array();
            $right = array();
            if(count($arr)<=1){
                return $arr;
            }
            for($i=1;$i<count($arr);$i++){
                if($arr[0]>$arr[$i]){
                    $left[] = $arr[$i];
                }else{
                    $right[] = $arr[$i];
                }
            }
            $left = kuaisu($left);
            $right = kuaisu($right);
            return array_merge($left,array($arr[0]),$right);
        }
    ?>
    ```

  • 相关阅读:
    H.264---CABAC---第四步--算术编码
    H.264---CABAC---第三步----确定上下文索引
    H.264---CABAC---第二步---待编码语法元素二值化
    H.264---CABAC---第一步---上下文变量的初始化
    H.264---CABAC---基础---二进制算术编码
    H.264---CAVLC---基础篇
    【mpeg2】MPEG-2简单码流分析
    【mpeg】MPEG2、MPEG4、H264的差异和简介
    【mpeg】MPEG2、MPEG4、H264的差异和简介
    【signal】傅里叶分析和FFT蝶形算法
  • 原文地址:https://www.cnblogs.com/redirect/p/6245025.html
Copyright © 2020-2023  润新知