数据结构与算法视频学习笔记

概述

  • 目标:时间效率高,存储量低

时间复杂度和空间复杂度

  • 大O记法
  • 常见的时间复杂度(从上到下,复杂度依次增加)
    O(1) 常数阶
    O(logn) 对数阶
    O(n) 线性阶
    O(nlog)
    O(n^2) 平方阶
    O(n^3) 立方阶
    O(2^n) 指数阶
    O(n!)
    O(n^n)
  • 最坏情况和平均情况
  • 空间复杂度

线性表

  • 定义:由零个或多个数据元素组成的有限序列
  • 前驱,后继
  • 抽象数据类型

    • eg: point(x,y,z)
    • 描述抽象数据类型的标准格式:

      ADT 抽象数据类型名
      Data
          数据元素之间逻辑关系的定义
      Operation
          操作
      endADT
      
  • 示例1:A与B并集
  • 线性表的存储结构:顺序存储结构、链式存储结构
  • 顺序存储结构封装需要三个属性
    • 起始位置
    • 最大存储容量
    • 当前长度
  • 插入操作、删除操作
  • 线性表顺序存储结构:存、读数据时间复杂度是O(1),插入、删除时间复杂度是O(n)
  • 链式存储结构

    • 结点(Node)
      • 数据域
      • 指针域
        • 指针/链
    • n个结点链接成一个链表
    • 单链表
      • 头指针:第一个结点的存储位置
        • 第一个结点的数据域一般不存储信息,也可以存放链表的长度
        • 头指针不能为空
      • null:最后一个结点指针为空
    • 添加结点:

      s->next = p->next  
      p->next = s
      
    • 删除结点:

      p->next = p->next->next

  • 单链表的整表创建

    • 头插法
    • 尾插法
  • 单链表的整表删除
  • 顺序结构与链表的比较:
    • 顺序结构适合:经常查询的场合
    • 链表结构适合:经常插入和删除的场合
  • 静态链表
    • 插入操作
    • 删除操作
  • 循环链表
    • 初始化
    • 插入
    • 删除
  • 双向链表:用空间换取时间
    • 插入:代码顺序很重要
    • 删除

单链表小结:腾讯面试题

题目:快速找到未知长度单链表的中间节点。
思路:使用快慢指针

约瑟夫问题

题目:一个圈,每报数到3,则自杀,直到所有人都自杀了。
思路:循环链表

判断单链表中有环

思路:快慢指针/一个指针每次走一步,另一个指针每次都从头走

魔术师发牌问题

拉丁方阵问题

  • 栈是一种重要的线性结构
  • 栈是一个后进先出的线性表,它要求只在表尾进行删除和插入操作。
  • 术语:
    • 栈顶(Top)
    • 栈底(Bottom)
    • 进栈(Push)
    • 出栈(Pop)
  • 栈的顺序存储结构(常用)
  • 栈的链式存储结构

将二进制数转换为十进制数,二进制转换为八进制

逆波兰计算器

中缀表达式转换为后缀表达式

队列

  • 队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
  • 先进先出
  • 从后面入队列,从前面出队列
  • 队列的顺序存储结构
  • 队列的链式存储结构(常用):链队列
  • 循环队列

递归

  • 递归效率低,最好用迭代代替
  • 斐波那契数列的递归实现
  • 递归实现字符串反向输出:利用了递归的回退
  • 分治思想:
    • eg:折半查找

汉诺塔(递归)

八皇后问题(递归)

字符串

  • 度:结点拥有的子树数
  • 分支结点、叶节点
  • 根为第一层
  • 深度
  • 森林

树的存储结构

  • 双亲表示法
  • 孩子表示法
  • 双亲孩子表示法

二叉树

  • 不存在度大于2的结点(但是可以是1或者0)
  • 左子树和右子树是有顺序的
  • 二叉树的五种基本形态
  • 特殊二叉树
    • 斜树
    • 满二叉树
      • 定义:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。
    • 完全二叉树
      • 定义:对一颗具有n个结点的二叉树按层序编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点位置完全相同,则这棵二叉树称为完全二叉树。
  • 二叉树性质
    1. 在二叉树的第i层上至多有2^(n-1)个结点(i>=1)
    2. 深度为k的二叉树至多有2^k-1个结点(k>=1)
    3. 对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1
    4. 具有n个结点的完全二叉树的深度为down{(log2 n)}+1
  • 二叉树的存储结构
    • 顺序存储
    • 链式存储(常用):二叉链表
  • 二叉树的遍历
    • 定义:二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次
    • 前序遍历
    • 中序遍历
    • 后序遍历
    • 层序遍历
  • 线索二叉树
    • 增加了线索,指示是左右孩子还是前驱后继
    • 中序遍历

树、森林及二叉树的相互转换

  • 树转换成二叉树
    • (1)在树中所有的兄弟结点之间加一连线
    • (2)对每个结点,除了保留与其长子的连线外,去掉该结点与其他孩子的连线
  • 森林转换成二叉树
    • (1)先将森林中的每棵树变为二叉树
    • (2)再将二叉树的根结点视为兄弟从左至右连在一起,就形成了一棵二叉树
  • 二叉树到树、森林的转换
    • (1)若结点x是其双亲y的左孩子,则把x的右孩子,右孩子的右孩子,……,都与y用连线连起来
    • (2)去掉所有双亲到右孩子之间的连线
  • 树与森林的遍历
    • 树的遍历:先根遍历、后根遍历
    • 森林的遍历:先根遍历、后根遍历
  • 重要性质:
    • 树、森林的先根遍历和二叉树的前序遍历结果相同
    • 树、森林的后根遍历和二叉树的中序遍历结果相同

Huffman树

  • 基本概念
    • 节点的路径长度
      • 从根结点到该结点的路径上的连接数
    • 树的路径长度
      • 树中每个叶子结点的路径长度之和
    • 结点带权路径长度
      • 结点的路径长度与结点权值的乘积
    • 树的带权路径长度(WPL,Weighted Path Length)
      • 树中所有叶子结点的带权路径长度之和
  • Huffman树:WPL值最小
  • 如何构造
    • 权值从小到大排序,后面类似编码的过程,小的是左孩子,大的是右孩子

定义

是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为G(V,E)。其中G表示一个图,V是图G中顶点的集合,E是图G中边的集合。

  • 无向边:无向偶(Vi,Vj)表示
  • 有向边:有向偶

图的存储结构

  1. 邻接矩阵
  2. 邻接表
  3. 十字链表:对有向图来说,有时候需要建立邻接表和逆邻接表2个表。十字链表可以把邻接表和逆邻接表很好整合在一起。
  4. 邻接多重表
  5. 边集数组

图的遍历

最小生成树

  • 普里姆算法(Prim算法):适合稠密图
  • 克鲁斯卡尔算法(Kruskal算法):适合稀疏图

最短路径

  • 迪杰斯特拉算法(Dijkstra算法):O(n^2)
  • 弗洛伊德算法(Floyd算法):O(n^3)

拓扑排序

  • 无环图(DAG图)
  • AOV网:在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的图,我们称之为AOV网(Activity On Vertex Network)。
  • 拓扑序列

关键路径

  • AOE网:在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间,这种有向图的边表示活动的网,我们称之为AOE网(Activity on Edge Network)。

查找算法

  • 静态查找
    • 顺序查找(可以优化,加一个哨兵):O(n)
    • 折半查找:O(log2n),下面两种是折半查找的改进:
      • 插值查找(按比例查找):关键在mid的计算上,O(log2n),适合数据比较均匀的情况
      • 斐波那契查找(黄金比例查找)
    • 线性索引查找
      • 稠密索引
      • 分块索引
      • 倒排索引
  • 动态查找
    • 二叉排序树
      • 二叉排序树又称二叉查找树,它或者是一棵空树,或者是具有下列性质的二叉树:
        • 若它的左子树不为空,则左子树上所有结点的值均小于它的根结构的值;
        • 若它的右子树不为空,则右子树上所有结点的值均大于它的根结构的值;
        • 它的左、右子树也分别为二叉排序树。
      • 查找
      • 插入
      • 删除(比较麻烦)
        • 删除叶子结点
        • 删掉只有左子树或者右子树的结点
        • 删除有左子树和右子树的结点
    • 平衡二叉排序树
      • 平衡二叉树要么是一棵空树,要么它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。
      • 左旋,右旋
    • 多路查找树
      • 2-3树
        • 2-3树的所有叶子都在同一层次
        • 插入
          • 空树:直接构造一个2结点
          • 插入到2结点的叶子结点:直接插入,构造成3结点
          • 插入到3结点的叶子,但是双亲结点是2结点:扩展双亲
          • 一直是3结点:增加树的高度,从下向上拆
        • 删除
          • 位于3结点的叶子结点:直接删
          • 位于2结点的叶子结点
            • 双亲是2结点,且双亲有一个3结点孩子:左旋转
            • 双亲是2结点,且双亲有一个2结点孩子:找后继,然后旋转
            • 双亲是3结点:双亲变成2结点
            • 所有结点都是2结点:减少树的高度
          • 不是叶子结点
            • 位于2结点的双亲
            • 位于3结点的双亲
      • 2-3-4树
        • 插入
        • 删除
      • B树
        • B树是一种平衡的多路查找树,2-3树和2-3-4树都是B树的特例。我们把结点最大的孩子树数目称为B树的阶,因此,2-3树是3阶B树,2-3-4树是4阶B树。
    • 散列表(哈希表)
      • 记录的存储位置=f(关键字)
      • 适合一对一查找
      • 散列函数
        • 构造原则:计算简单、分布均匀
        • 直接定址法
        • 数字分析法
        • 平方取中法
        • 折叠法
        • 除留余数法
        • 随机数法
      • 冲突处理
        • 开放定址法
        • 再散列函数法
        • 链地址法
        • 公共溢出区法

排序

冒泡排序

O(n^2)

选择排序

O(n^2),移动的次数少了

直接(简单)插入排序

希尔排序

O(nlogn)
直接插入排序在基本有序的情况下,效率是很高的
对直接插入排序的改进

堆排序

O(nlogn)
对选择排序的改进
完全二叉树
大顶堆、小顶堆

归并排序

快速排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
程序 = 数据结构 + 算法  程序是为了解决实际问题而存在的。然而为了解决问题,必定会使用到某些数据结构以及设计一个解决这种数据结构算法。如果说各种编程语言是程序员的招式,那么数据结构算法就相当于程序员的内功。编程实战算法,不是念PPT,我们讲的就是实战与代码实现与企业应用。程序 = 数据结构 + 算法                ——图灵奖得主,计算机科学家N.Wirth(沃斯)作为程序员,我们做机器学习也好,做python开发也好,java开发也好。有一种对所有程序员无一例外的刚需 —— 算法数据结构日常增删改查 + 粘贴复制 + 搜索引擎可以实现很多东西。同样,这样也是没有任何竞争力的。我们只可以粘贴复制相似度极高的功能,稍复杂的逻辑没有任何办法。语言有很多,开发框架更是日新月异3个月不学就落后我们可以学习很多语言,很多框架,但招聘不会考你用5种语言10种框架实现同一个功能。真正让程序员有区分度,企业招聘万年不变的重点 —— 算法数据结构算法代表程序员水平的珠穆朗玛。如果说各种编程语言是程序员的招式,那么数据结构算法就相当于程序员的内功。 想写出精炼、优秀的代码,不通过不断的锤炼,是很难做到的。 开这个系列的目的是为了自我不断积累。不积跬步无以至千里嘛。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值