总结一下我复习过的算法和mysql

1.数据结构分类

  • 集合关系:简单的集中在一起
  • 线性结构:一对一的关系
  • 树形结构:一对多的层级关系
  • 图形结构:多对多的关系

2.什么是链表数据结构?
一个元素,他会存一个指针指向相邻元素的地址。
分双向和单向 链表
双向链表:存了下一个元素的地址还有上一位的地址。

比如:mysql的叶子节点就用的链表结构,叶子节点存的是数据。

3.跳表的算法复杂度是多少?为什么?
跳跃表是一种随机化的数据结构,在查找,插入和删除这些字典操作上,其效率可比拟于平衡二叉树(如红黑树),大多数操作只需要O(logn)平均时间

基于有序单链表,在链表的基础上,每个节点不只包含一个指针,还可能包含多个指向后继节点的指针,这样就可以跳过一些不必要的节点,从而加快查找,删除等操作。传统的单链表是一个线性结构,向有序的链表插入,查找一个结点需要O(n)的时间,如果使用跳跃表,就可以减少查找所需的时间。
在这里插入图片描述

4.跳表用在哪里?
redis的有序集合用到了跳表。(有点像范围,像树的结构)

5.链表用在哪里?
mysql limit 2,4 其实2需要扫描,但是4不需要扫描,因为他是个链表
索引需要寻址,全表扫描2
如果有索引就查找的快了

6.算法具有的五个基本特性是什么?
算法具有五个基本特性:输入,输出,有穷性,确定性和可行性

7.堆的理解?
堆就是数组实现的二叉树,所以没有使用父指针或者子指针,堆根据"堆属性"来排序,堆属性 决定了树种节点的位置。
堆的常用方法

  • 构建优先队列
  • 支持堆排序
  • 快速找到一个集合中的最小值(或最大值)
    最大堆:
    在这里插入图片描述

8.什么是二叉搜索树?
一个节点分两个叉,右节点数值大于左节点

9.数据库索引为什么用B+树而不用红黑树呢?
2-3树对二叉树的优化

2-3树优化后就是红黑树,
现代磁盘的结构设计,这里讲了b b+ 树
在这里插入图片描述
B-树
1.B-树 中间节点也存数据
mongodb底层是B-树 (ps:之前都不知道)
如果limit 就很麻烦了,

B+树 log(n)
1.中间节点不保存数据,保存的是索引, 叶子节点保存的所有数据
2.叶子节点是一个链表结构
有个概念是叶子节点 (mysql的数据存在叶子节点上了,用链表连接方便范围查询,非叶子节点是索引)

10.mysql磁盘IO的主要过程?
需要先从磁盘读到内存,那就产生一次io,优化什么,优化的是io
树有多少层就有多少io。层级越小,io越小
二叉树,层级太高。

11.B树的优势是什么?
IO次数足够少,
B+树对B树又进行了一次优化。

12.为什么经常修改,修改次数大于查询次数的mysql表不适合索引?
因为索引要重建。因为是平衡二叉树,树结构要重建(叫索引重建)
但是不一定每次修改都重建索引,因为mysql有一个缓冲区。有个日志分批次的。
13.php的sql数据结构的理解?
php.net/manual/zh/book.spl.php

mysql 架构:连接器->查询缓存->分析器->优化器->执行器

B+树数据全部存放在叶子节点,B+树中查询任意数据的次数,都是n次,n表示的是B+树的高度
php7 不用下载包 ,拓展库就有,直接new 就能实现9种数据结构
在这里插入图片描述
这些会随着进程销毁而销毁

//堆 分为最大堆和最小堆 
//队列和栈都是线性结构 底层是 指针
//队列先进先出 (排队取票)
$q = new SplStack();//栈  先进后出  (便签)
$q[]=1;
$q[]=2;
$q[]=3;
$q->push(4);
var_dump($q);
$q->rewind();//翻
var_dump($q);
while($q->valid())
{
    echo $q->current().'<br>';
    $q->next();
}

括号序列

$str = "[{[]]}}";
function se($str)
{
    $len = strlen($str);
    if($len<2) return false;
    if($len%2 ==1) return false;
    $tmp = array(
        '['=>']',
        '('=>')',
        '{'=>'}'
    );
    $mid = array();
    for($i=0;$i<$len;$i++)
    {
        if(isset($tmp[$str[$i]]))
        {
            $mid[] = $str[$i];
        }
        elseif($str[$i] == $tmp[$mid[count($mid)-1]])
        {
            array_pop($mid);
        }
        else
        {
            return false;
        }
    }

    if($mid) return false;
    return true;
}

var_dump(se($str));

冒泡排序: 大家都见鱼吐泡泡吧,其实冒泡排序就是两个数换位置,每次都把大的数放后面(从小到大)
一次遍历只能解决的是数组当前最大的数会移动到数组尾部,
两次遍历就能将所有位置都按照从小到大的顺序排列了

$arr = [1,3,5,4,8];
function select($arr)
{
    $num = count($arr);
    for($i=0;$i<$num;$i++)         //0,1,2,3,4
    {
        for($j=$num-1;$j>$i;$j--) //   4,3,2,1   3,2 
        {
            if($arr[$j-1]>$arr[$j])
            {
                $tmp = $arr[$j];
                $arr[$j] = $arr[$j-1];
                $arr[$j-1] =$tmp;
            }
        }
    }
    return $arr;
}

总结: 外从小到大 内从大到小, 内key要大于外key

快排 啥是快排思想就是以一个为基准,小于的放左边,大于它的放右边。(ps:好像军训站队)

function quick($arr)
{
    $num = count($arr);
    if($num<2)
    {
        return $arr;
    }
    $mid = $arr[0];
    $left = array();
    $right = array();
    for($i=1;$i<$num;$i++)
    {
        if($arr[$i]<$mid)
        {
            $left[] = $arr[$i];
        }
        else
        {
            $right[] = $arr[$i];
        }
    }
    $left = quick($left);
    $right = quick($right);
    return array_merge($left,array($mid),$right);
}

二分法

function two($num,$target)
{
    $n = count($num);
    $left = 0;
    $right = $n-1;
    while($left<=$right)
    {
        $mid = $left + floor(($right-$left)/2);
        if($num[$mid]==$target)
        {
            return $mid;
        }
        elseif($num[$mid]>$target)
        {
            $right = $mid-1;
        }
        else
        {
            $left = $mid+1;
        }
    }
    return false;
}
var_dump(two($num,$target));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mr.杰瑞

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

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

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

打赏作者

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

抵扣说明:

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

余额充值