数据结构定义
- 数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及它们之间的关系和操作等相关问题的学科。
- 数据结构阐述了数据的逻辑结构和存储结构及其操作。
- 程序设计的实质:对确定的问题选择一种好的结构,加上设计一种好的算法。
- 程序设计=数据结构+算法
- 基本概念和术语
- 数据:描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。包括整型、实数型等数值类型,还包括声音、图像视频等非数值类型。
- 数据元素:组成数据的、有一定意义的基本单位,在计算机中通常作为整体处理。
- 数据项:一个数据元素可以由若干个数据项组成。数据项是数据不可分割的最小单位。
- 数据对象:性质相同的性质元素的集合,是数据的子集。
- 数据结构:不同数据元素之间不是独立的,而是存在特定的关系,我们把这些关系称为结构。而数据结构就是相互之间存在一种或多种特定关系的数据元素的集合。
逻辑结构与物理结构
- 数据结构分为逻辑结构和物理结构。
- 逻辑结构:数据对象中数据元素之间的相互关系。
- 集合结构:数据元素同属于一个集合。
- 线性结构:数据元素是一对一的关系。
- 树形结构:数据元素之间存在一种一对多的层次关系。
- 图形结构:数据元素是多对多的关系。
- 物理(存储)结构:数据的逻辑结构在计算机中的存储形式。
- 关键:数据的存储形式应该正确反映数据元素之间的逻辑关系。如何存储数据元素之间的逻辑关系,是实现物理结构的重点和难点。
- 数据元素的存储结构形式有两种:顺序存储和链式存储。
- 顺序存储结构:将数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。如数组。
- 链式存储结构:将数据元素存放在任意的存储单元内,这组存储单元可以是连续的,也可以是不连续的。数据元素的存储关系不反应其逻辑关系,使用指针存放数据元素的地址,这样通过地址就可以找到相关联数据元素的位置。
抽象数据类型
- 数据类型
- 定义:一组性质相同的值的集合及定义在此集合上的一些操作的总称。
- 如每个变量、常量和表达式都有各自的取值范围,数据类型用来说明变量或表达式的取值范围和所能进行的操作。
- 抽象数据类型(abstract data type, ADT)
- 定义:指一个数学模型及定义在该模型上的一组操作。
- 抽象的意义在于数据类型的数学抽象特性。
- 抽象数据类型体现了程序设计中问题分解、抽象和信息隐藏的特性。
- 数据对象、数据对象中各元素之间的关系、对数据元素的操作,如整型。
- 描述抽象数据类型的标准形式:
ADT 抽象数据类型名 Data 数据元素之间逻辑关系的定义 Operation 操作1 初始条件 操作结果描述 操作2 ...... 操作n ...... endADT
常见的数据结构
- 10个重要的数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie树
- 线性表
- 数组
- 链表
- 单链表
- 双向链表
- 循环链表
- 双向循环链表
- 静态链表
- 队列
- 普通队列
- 双链队列
- 阻塞队列
- 并发队列
- 阻塞并发队列
- 栈
- 顺序栈
- 链式栈
- 散列表
- 散列函数
- 冲突解决
- 链表法
- 开放寻址
- 其他
- 动态扩容
- 位图
- 树
- 二叉树
- 平衡二叉树
- 二叉查找树
- 平衡二叉查找树
- AVL树
- 红黑树
- 完全二叉树
- 满二叉树
- 多路查找树
- B树
- B+树
- 2-3树
- 2-3-4树
- 堆
- 小顶堆
- 大顶堆
- 优先级队列
- 斐波那契堆
- 二项堆
- 其他
- 树状数组
- 线段树
- 二叉树
- 图
- 图的存储
- 邻接矩阵
- 邻接表
- 拓扑排序
- 最短路径
- 关键路径
- 最小生成树
- 二分图
- 最大流
- 图的存储
算法(Algorithm)
- 算法:算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
- 算法的特性:输入、输出、有穷性、确定性、可行性。
- 输入输出:零个或多个输入,一个或多个输出。
- 有穷性:算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成。
- 确定性:算法的每一个步骤都具有明确的含义,不会出现二义性。
- 可行性:算法的每一步都是可行的,能够通过执行有限次数完成。
算法设计的要求
- 正确性
- 无语法错误
- 对于合法输入能够产生满足要求的输出
- 对于非法输入能够得出满足规格说明的输出
- 对于精心选择的、恶意刁难的测试数据能够产生满足要求的输出
- 可读性:便于阅读、理解和交流。
- 健壮性:当输入数据不合法时,能做出相关处理。
- 时间效率高、存储量低。
算法时空复杂度
- 算法时间复杂度
- 定义:在进行算法分析时,语句总的执行次数 T ( n ) T(n) T(n)是关于问题规模n的函数,进而分析 T ( n ) T(n) T(n)随n的变化情况并确定 T ( n ) T(n) T(n)的数量级。算法的时间复杂度,记作: T ( n ) = O ( f ( n ) ) T(n)=O(f(n)) T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和 f ( n ) f(n) f(n)的增长率相同。称作算法的渐进时间复杂度,简称为时间复杂度。其中 f ( n ) f(n) f(n)是问题规模n的某个函数。
- 大O记法:
- 用常数1取代运行时间中的所有加法常数
- 在修改后的运行次数函数中,只保留最高阶项
- 如果最高阶存在且不是1,则去除与这个项相乘的常数
- 特点:
- 表示语句总的执行次数与问题规模的函数
- 使用大O记号
- 忽略常数
- 指最坏情况下的运行时间
- 常见的时间复杂度比较:
O ( 1 ) < O ( l o g n ) < O ( n 1 / 2 ) < O ( n ) < O ( n l o g n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1)<O(log n)<O(n^{1/2})<O(n)<O(nlog n)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n) O(1)<O(logn)<O(n1/2)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn) - 分析角度
- 最好时间复杂度
- 最坏时间复杂度
- 平均时间复杂度
- 均摊时间复杂度
- 算法空间复杂度
- 定义:算法的空间复杂度通过计算算法所需的存储空间实现,计算公式记作: S ( n ) = O ( f ( n ) ) S(n)=O(f(n)) S(n)=O(f(n)),其中n为问题的规模, f ( n ) f(n) f(n)为语句关于n所占存储空间的函数。
- 算法运行过程中需要占用的内存字节数。
基本算法
- 10个重要的算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
- 递归
- 排序
- O(n^2)
- 冒泡
- 插入
- 选择
- 希尔
- O(nlogn)
- 归并排序
- 快速排序
- 堆排序
- O(n)
- 基数排序
- 计数排序
- 桶排序
- O(n^2)
- 搜索
- 深度优先搜索
- 广度优先搜索
A*启发式搜索
- 查找
- 线性表查找
- 树结构查找
- 散列表查找
- 字符串匹配
- 朴素
- KMP
- Robin-Karp
- Boyer-Moore
- AC自动机
- Trie
- 后缀数组
- 穷举
- 求n个数的全排列
- 八皇后问题
- 分而治之(减而治之)
- 二分查找(减而治之)
- 归并排序(分而治之)
- 贪心
- 最小生成树
- 单源最短路径
- 动态规划
- 背包问题
- 士兵路径问题
- 回溯
- 其他
- 数论
- 计算几何
- 概率分析
- 并查集
- 拓扑网络
- 矩阵运算
- 线性规划
推荐书单
- 针对入门的趣味书
- 《大话数据结构》:400多页,结合生活中的例子对每个数据结构和算法进行了讲解
- 《算法图解》:不到200页像小说一样的算法入门书
- 针对特定编程语言的教科书
- 《数据结构与算法分析 :C语言描述》
- 《数据结构与算法分析:C++描述》
- 《数据结构与算法分析 :Java语言描述》
- 《数据结构与算法 JavaScript 描述》
- 《数据结构与算法:Python 语言描述》
- 面试必刷宝典
- 《剑指offer》:几乎包含了所有常见的、经典的面试题
- 《编程珠玑》:有很多针对海量数据的处理技巧
- 《编程之美》:质量很高,题目稍难
- 经典书籍
- 《算法导论》:章节安排不是循序渐进的,里面充斥着各种算法的正确性、复杂度的证明推导,数学公式比较多
- 《算法》:偏重讲算法,内容不够全面
- 《计算机程序设计艺术》:殿堂级经典书,其深度、广度、系统性、全面性是其他所有数据结构和算法书籍都无法比拟的
- 闲暇阅读
- 《算法帝国》
- 《数学之美》
- 《算法之美》