第七章 算法

一. 算法的基本概念

一个问题可以有多个算法,每种算法效率不同
一个算法具有五个特征:有穷性,确切性、输入项、输出项、可行性

  1. 算法评定
    算法分析的目的在于选择合适算法和改进算法
    一个算法的评价主要从时间复杂度和空间复杂度来考虑

  2. 时间复杂度
    执行算法所需要时间的计算工作量。一般来说,计算机算法是问题规模n的函数f(n),算法的时间复杂度也因此记做T(n)=O(f(n))
    问题的规模n越大,算法执行的时间的增长率与f(n)的增长率正相关,称作渐进时间复杂度

  3. 时间复杂度计算方式

得出算法的计算次数公式
线性阶 O(n)

O(n) 1+2+3+...+n

常数阶:O(1)

function demo($n){
    echo $n;
    echo $n;
}

function demo1($n){
  echo  ($n+1)*$n/2
}

平方阶O(n^2) n^2+n+1

function demo($n)
{
    $sum = 0;
    for($i=0;$i<$n;$i++){
        for($j=0;$j<$n;$j++){
            $sum+=$j;
        }
        $sum+$i;
    }
    echo $sum;
}

立方阶O(n^3) n^3
如果最高阶存在且不是1,则去除与这个项相乘的常数

  1. 常见时间复杂度:常数阶、线性阶、平方阶、立方阶、对数阶、nlog2n阶、指数阶
    O(1)>O(log2n)>O(n)>O(nlog2n)>O(n2)>O(n3)>O(2n)>O(n!)>O(nn)

  2. 时间复杂度其他概念
    最坏情况:最坏情况时的运行时间,一种保证,如果没有特别说明,说的时间复杂度即为最坏情况的时间复杂度
    平均情况:期望的运行时间

  3. 空间复杂度
    算法需要消耗的内存空间,记做S(n)= O(f(n))
    包括程序代码所占用的空间,输入数据所占用的空间和辅助变量所占用的空间这三个方面
    计算和表示方法与时间复杂度类似,一般用复杂度的渐进性来表示

  4. 空间复杂度计算方式
    有时用空间换取时间
    冒泡排序的元素交换,空间复杂度0(1)

  5. 排序算法
    冒泡排序、直接插入排序、希尔排序、选择排序、快速排序、堆排序、归并排序

冒泡排序:两两相邻的数进行比较,如果反序就交换,否则不交换
时间复杂度:最坏(O(N2),平均(O(N2)))
空间复杂度:O(1)

直接插入排序
每次从无序表中取出第一个元素,把他输入到有序表的合适位置,使有序表依然有序
时间复杂度:最坏(O(N2),平均(O(N2)))
空间复杂度:O(1)

希尔排序
把待排序的数据增量分成几个子序列,对子序列进行插入排序,知道增量为1,直接进行插入排序;增量的排序,一般是数组的长度的一半,再变为原来增量的一半,知道增量为1
时间复杂度:最坏(O(N^2),平均(O(n*log2n)))
空间复杂度:O(1)

选择排序
每次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,知道全部待排序的数据元素排完
时间复杂度:最坏(O(N2),平均(O(N2)))
空间复杂度:O(1)

快速排序
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按照此方法对这两部分数据分别进行快速排序,整个排序过程可以递归完成
时间复杂度:最坏(O(N^2),平均(O(n*log2n)))
空间复杂度:最坏(O(n),平均(O(log2n)))

堆排序
把待排序的元素按照大小在二叉树位置上排序,排序好的元素要满足:父节点的元素要大于等于子节点;这个过程叫做堆化过程,如果根节点存放的是最大的数,则叫做大根堆,如果是最小,就叫小根堆,可以把根节点拿出来,然后再堆化,循环到最后一个节点
时间复杂度:最坏(O(nlog2n)),平均(O(nlog2n)))
空间复杂度:O(1)

归并排序
将两个或两个以上有序表合并成一个新的有序表,即把待排序序列分成若干个有序的子序列,再把有序的子序列合并为整体有序序列
时间复杂度:最坏(O(nlog2n)),平均(O(nlog2n)))
空间复杂度:O(n)

总结:
快速排序、归并排序的理想时间复杂度都是O(nlog2n),但快速排序的时间复杂度并不稳定,最坏情况下复杂度为O(n^2),所以最理想的算法还是归并排序

二分查找
原理:从数组的中间元素开始,如果中间元素正好是要查找的元素,搜索结束,如果某一个特定元素大于或者小于中间元素,则在数组大于或者小于中间元素的那一半中查找,而且跟开始一样从中间开始比较,如果某一步骤数组为空,代表找不到。
时间复杂度:最坏(O(log2n)),平均(O(log2n)))
空间复杂度:迭代O(1),递归(O(log2n))

顺序查找
原理:按照一定的顺序检查数组中的每一个元素,直到找到所要查找的特定值为止。
时间复杂度:最坏(O(n)),平均(O(n)))
空间复杂度:O(1)
总结:
二分查找算法的时间复杂度最差是O(log2n),顺序查找的时间复杂度最差为O(N),所以二分查找法更快,但是递归情况下,二分查找法更消耗内存,时间复杂度为O(log2n)

二.常见数据结构

  1. Array
    数组,最简单而且应用最广泛的数据结构之一
    特性:使用连续的内存来存储,数组中的所有元素必须是相同的类型或类型的衍生(同质数据结构)、元素可以通过下标直接访问

  2. linkedList
    链表,线性表的一种,最基本、最简单也是最常用的数据结构
    特性:元素之间的关系是一对一的关系(除了第一个还最后一个元素,其他元素都是首尾相接)、顺序存储结构和链式存储结构两种存储方式

  3. Stack
    栈,和队列相似,一个带有数据存储特性的数据结构
    特性:存储数据是先进后出的、栈只有一个出口,只能从栈顶部增加或移除元素

  4. Heap
    堆,一般情况下,也叫二叉堆,近似完全二叉树的数据结构
    特性:子节点的键值或者索引总小于他的父节点,每个节点的左右子树又是一个二叉堆,根节点最大的堆叫最大堆或者大根堆、最小的叫最小堆或者小根堆

  5. list
    线性表,由零个护着多个数据元素组成的有序序列
    特性:线性表是一个序列,0个元素构成的线性表是空表、第一个元素无先驱、最后一个元素无后继、其他元素都只有一个先驱和后继、有长度,长度是元素个数,长度有限

  6. doubly-linked-list
    双向链表
    特性:每个元素都是一个对象,每个对象有一个关键字key和两个指针(next和prev)

  7. queue
    队列
    特性:先进先出(FIFO),并发中使用,可以安全将对象从一个任务传给另一个任务

  8. set
    集合
    特性:保存不重复元素

  9. map
    字典
    特性:关联数组,也叫作字典或者键值对

  10. graph

    特性:通常使用邻接矩阵和邻接表表示,前者易实现但对于稀疏矩阵会浪费较多空间、后者使用链表的方式存储信息但对于图搜索时间复杂度较高

三.其他逻辑算法

  1. 斐波那契数列
  2. 写一个函数,实现字符串open_door=>OpenDoor
function strHandle($str)
{
    $arr = explode('_',$str);
    $return = '';
    foreach($arr as $val)
    {
        $return.= ucfirst($val);
    }
    return $return;
}

四.模拟内置函数

  1. 不使用PHP内置函数反转字符串
function str_rev($str)
{
    for($i=0;true;$i++)
    {
      if(!isset($str[$i]))
      {
        break;
      }
    }
    $return = '';
    for($j=$i-1;$j>=0;$j--)
    {
        $return .= $str[$j];
    }
    return $return;
}
  1. 不使用array_merge,完成多个数组的合并
function array_mer()
{
    //动态获取参数
    $arrays = func_get_args();
    foreach($arrays as $arr)
    {
        if(is_array($arr))
        {
            foreach($arr as $val)
            {
                $return[] = $val;
            }
        }
    }
    return $return;

}
array_mer();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我峰兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值