数据结构算法归纳

递推思想

例如:斐波那契数列:1 1 2 3 5 8 13 …… 需求:求出指定位置N对应的值是多少。
博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

//递推思想
//需求 1 1 2 3 5 8 13 ...... 求出指定位置N对应的值是多少

$f[1] = 1;
$f[2] = 1;
//列出数组元素
$des = 15;
for($i = 3;$i <= $des;$i++){
    
    
    $f[$i] = $f[$i-1] + $f[$i-2];
}

echo '<pre>';
print_r($f);
//建立函数寻找
function my_recursive($des){
    
    
    if($des == 1 || $des == 2) return 1;

    //开始计算
    $f[1] = 1;
    $f[2] = 1;

    for($i = 3;$i <= $des;$i++){
    
    
        $f[$i] = $f[$i-1] + $f[$i-2];
    }
    return $f[$des];
}

echo '第15个元素的值为:' . my_recursive(15);

效果图:
在这里插入图片描述

递归思想

递归思想很重要的点:递归点递归出口
递归点:发现当前问题可以有解决当前问题的函数,去解决规模比当前小一点的问题。比如:F(N) = F(N-1)+F(N-2);
递归出口:当前问题解决时,已经到达(必须有)最优子问题,不能再次调用函数
本质:空间换时间

//递归思想
//用递归的思想求斐波那契数列
//递归一定有函数

function recursion($n){
    
    
    //递归出口
    if($n ==1 || $n == 2) return 1;

    //递归点:求N得值,与求N-1的值一模一样,只是N-1的规模比N小
    return recursion($n-1) + recursion($n-2);
}

//调用
echo recursion(15);

冒泡排序

冒泡排序(Bubble Sort)是一种计算机科学领域的比较简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经完成排序完成。

冒泡思路:
1、 比较相邻的元素,如果第一个没第二个大,就交换他们两个
2、 对每一个相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后元素应该会是最大的数。
3、 针对所有的元素重复以上的步骤,除了最后一个
4、 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

//数组排序算法:冒泡排序

$arr = array(1,4,2,9,7,5,8);
$a = 0;

//2、想办法让下面可以每次找出最大的代码重复执行
for($i = 0; $i < count($arr)-1; $i++){
    
    
//1、想办法将最大的值放到右边
    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;
        }
        $a++;
    }
}


echo '<pre>';
print_r($arr);
echo '计算次数:' . $a;

效果图:
在这里插入图片描述

选择排序

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(最大)的一个元素,存放在序列的起始位置,直到全部排序的数据元素排完。选择排序是最不稳定的排序方法(比如序列[5,5,3])第一次就将第一个 5与3交换,导致第一个5挪动到第二个5后面
思路:
1、 假设第一个元素为最小元素,记下下标
2、 寻找右侧剩余的元素,如果有更小的,重新记下最新的下标
3、 如果有新的最小的,交换两个元素
4、 往右重复以上步骤,直到元素本身是最后一个

//数组排序算法:选择排序

$arr = array(1,5,2,9,6,3,4);

//1、确定要交换多少次,一次只能找到一个最小的,需要找到数组长度对应的次数
for($i = 0,$len = count($arr); $i < $len; $i++){
    
    
    //2、假设当前第一次已经排好序了
    $min = $i;
    //3、拿该最小的取比较剩余的其他
    for($j = $i+1; $j < $len; $j++){
    
    
        //4、比较当前最小值和指定值
        if($arr[$j] < $arr[$min]){
    
    
            //说明当前指定的min不合适
            $min = $j;
        }
    }

    //5、交换最小值的小标
    if($min != $i){
    
    
        $temp = $arr[$i];
        $arr[$i] = $arr[$min];
        $arr[$min] = $temp;
    }
}
echo '<pre>';
print_r($arr);

效果图:
在这里插入图片描述

插入排序

插入排序是将一个数据插入到已经排好序的有序数据中。
思路:
1、 认定第一个元素已经排好序
2、 取出第二个元素,作为待插入数据
3、 与已经排好序的数组的最右侧开始进行比较
4、 如果后面的小于前面的:说明前面已经拍好序的那个数组元素不在对的位置(向后移一位),然后让新的元素填充进去
5、 重复前面的步骤:直到当前元素插入到对的位置

//php数组排序:插入排序
$arr = array(4,2,6,8,9,5);

//1、确定要插入的次数(同时假设第一个位置是对的)
for($i = 1, $len = count($arr); $i < $len; $i++){
    
    
    //2、取出当前要插入的元素值
    $temp = $arr[$i];

    //标记:默认说明当前要插入的数组位置是对的
    $change = false;
    //3、让该数据与前面已经排好序的数组元素重复比较,直到位置正确
    for($j = $i - 1;$j >= 0; $j--){
    
    
        //比较
        if($arr[$j] > $temp){
    
    
            $arr[$j+1] = $arr[$j];
            //$arr[$j] = $temp;

            //说明前面顺序位置有不合适的位置
            $change = true;
        }else{
    
    
            //说明当前带插入元素,比前面大,位置正确
            break;
        }
    }
    //判断位置是否有变动
    if($change){
    
    
        //有数据移动:占错位置了
        $arr[$j+1] = $temp;
    }
}

echo '<pre>';
print_r($arr);

快速排序

快速排序(Quick sort)是对冒泡排序的一种改进。通过一趟排序将要排序的数据分割成独立的两部分,其中一部分所有数据比另外一部分都小,然后再按照此方法对这两部分分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
算法思路:
1、 从数组中选一个元素(通常第一个)作为参考
2、 定义两个数组,将目标数组中剩余的元素与参考元素挨个比较;小的放一个数组,大的放一个数组
3、 执行完后,前后数组顺序不确定,但确定了自己的位置
4、 将得到的小数组按照第1到3重复执行
5、 回溯最小数组(1个元素)

//php数组排序:快速排序

$arr = array(5,6,3,4,9,2,7,8);

//快速排序
function quick_sort($arr){
    
    
    //递归出口
    $len = count($arr);
    if($len <= 1) return $arr;

    //取出某个元素。然后将剩余的数组元素,分散到两个不同的数组中
    $left = $right = array();

    for($i = 1; $i < $len; $i++){
    
    
        //第一个元素作为比较元素
        //比较:小的放left,大的放right中
        if($arr[$i] < $arr[0]){
    
    
            $left[] = $arr[$i];
        }else{
    
    
            $right[] = $arr[$i];
        }
    }

    //left和right没有排好序:递归点
    $left = quick_sort($left);
    $right = quick_sort($right);

    //合并三个“数组”
    return array_merge($left,(array)$arr[0],$right);

}

echo '<pre>';
print_r(quick_sort($arr));

归并排序

归并排序
归并排序(merge sort)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使用每个子序列有序,在使子序列端间有序,然后将两个有序表合并成一个有序表,成为二路归并。

归并排序算法是:
1、 将数组分成两个数组
2、 重复步骤1将数组拆分为两个最小单元
3、 申请空间,使其大小为两个已经排序序列至和,该空间用来存放合并后的序列
4、 设定两个指针,最初位置分别为两个已经排序序列的起始位置
5、 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
6、 重复步骤3到某一指针超出序列尾
7、 将另一序列剩下的所有元素直接复制合并序列尾

//PHP数组算法:归并排序

/**二路归并*/
$arr1 = array(1,3,5);
$arr2 = array(2,4,6);

//取出数组用于归并空间
$arr3 = array();

while(count($arr1) && count($arr2)){
    
    
    //如果数组中都还有数据,则循环
    $arr3[] = $arr1[0] < $arr2[0] ? array_shift($arr1) :array_shift($arr2);
}
//print_r(array_merge($arr3,$arr1,$arr2));

/**归并排序*/
$arr = array(4,7,2,1,5,9,3,5,6);

//归并排序函数
function merge_sort($arr){
    
    
    //递归出口
    $len = count($arr);
    if($len <= 1) return $arr;

    //拆分
    $middle = floor($len/2);
    $left = array_slice($arr,0,$middle);
    $right = array_slice($arr,$middle);

    //递归出口
    $left = merge_sort($left);
    $right = merge_sort($right);

    //假设左边和右边都已经排序好了
    $arr3 = array();
    while(count($left) && count($right)){
    
    
        //只要$left和$right都还有元素
        $arr3[] = $left[0] < $right[0] ? array_shift($left) :array_shift($right);
    }
    return array_merge($arr3,$left,$right);
}
echo '<pre>';
$t1 = microtime(true);
print_r(merge_sort($arr));
$t2 = microtime(true);
echo '耗时' . round($t2 - $t1,3).;

查找算法

查找算法含义:
查找是在大量信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算,查找算法是指实现查找过程中对应的代码结。就是大型数组中快速定位想要的元素。

顺序查找算法
顺序查找也称为线性查找,从数据结构线性表的一段开始,顺序扫描,依次将扫描的节点关键字与给定k值比较,若相等则表示查找成功,若扫描结束仍没有找到关键字等于k的结点,表示查找失败

二分查找算法
二分查找要求线形表中的结点按关键字升序或降序排列,用给定值k先于中间结点的关键字比较,中间结点把线性表分为两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找或查找结束发现表中没有这样的结点。

二分法查找代码:

//二分法查找
$arr = array(1,2,3,4,5,6,7);
$res = 100;

function check_break($arr,$res){
    
    
    //1、得到数组边界
    $right = count($arr)-1;
    $left = 0;

    //2、循环匹配
    while($right >= $left){
    
    
        //3、得到中间位置
        $middle = floor(($right + $left)/2);

        //4、匹配数据
        if($arr[$middle] == $res){
    
    
            return $middle + 1;
        }

        //没有找到
        if($arr[$middle] < $res){
    
    
            //值在右边
            $left = $middle + 1 ;
        }else{
    
    
            //值在左边
            $right  = $middle - 1;
        }
    }
    return false;
}

echo '<pre>';
var_dump(check_break($arr,$res));

如果对你有帮助,就点个赞吧!

猜你喜欢

转载自blog.csdn.net/weixin_43477545/article/details/106826943
今日推荐