数据结构绪论
数据结构的定义:
逻辑结构:集合、线性结构、树形结构、图形结构
物理结构:顺序、链接
算法绪论
分析算法运行时间时,要把基本操作的数量与输入规模关联起来,即将基本操作的数量表示成输入规模的函数
大O阶算法时间复杂度:
1、用常熟1取代时间中的所有加法常熟
2、在修改后的运行次数函数中,只保留最高阶项
3、如果最高阶项存在且不是1,去除与这个项相乘的常数
顺序结构和分支结构:O(1)
算法时间复杂度:
常数阶、线性阶、对数阶、平方阶
常用时间复杂度所耗费的时间从小到大依次是:
线性表(链表)
线性表
插入算法:
删除算法:
线性表顺序存储结构的优缺点:
头指针和头结点的异同
单链表数据的读取
单链表插入结点数据的思路
单链表删除结点的思路代码
单链表整表创建的算法思路:
单链表整表创建的代码:
单链表整表删除的算法思路
单链表整表删除的算法代码
单链表结构和顺序存储结构对比
其他链表结构1:静态链表(用数组描述的链表)
静态链表的插入:
1、将所有未被使用过的以及已经被删除的分量用游标连成一个链表
并将第一个结点作为待插入新结点
2、在第i个元素之前插入数据
静态表的删除
1、释放结点函数
2、删除列表中结点数据
静态链表特点
其他链表结构2:循环链表
其他链表结构3:双向链表
双向链表的插入
顺序:先搞定s的前驱和后继,在搞定后结点的前驱,最后搞定前结点的后继
双向链表的删除
线性表总结
栈与队列
栈:本质是线性表
栈顶:允许插入和删除数据的一端
特点:后进先出(LIFO结构:Last In First Out)
栈的顺序结构定义:
进栈:
出栈:
两栈共享空间
插入元素的代码
出栈:
栈的链式存储结构(链栈)
进栈
出栈
栈有一个很重要的应用:在程序设计语言中实现了递归。
栈的应用:用于四则运算(采用后缀表达式,从左到右遍历表达式的每个数字和符号,
遇到是数字就进栈,遇到是符号就将栈顶两个数字出栈,进行运算,运算结果进栈)
队列(先进先出FIFO,First In First Out)
本质:只允许一端进行插入操作(队尾),另一端进行删除的线性表(对头)
队列顺序存储
循环队列
计算队列长度公式:
循环队列满的条件是
循环队列入队代码
循环队列出队代码
队列的链式存储(只能尾进头出的单链表)
链队列入队操作:
链队列出队操作
串pp
串的顺序存储
串的链式存储
实现Index操作代码:
KMP模式匹配算法原理
首先定义模式匹配字符串各位位置的变化为一个数组,其函数定义如下
一个例子:
计算当前要匹配的串的数组
使用KMP实现Index操作
树
树相关结点定义:度
结点的层次:
数据结构对比
树的存储结构:双亲表示法、孩子表示法、孩子兄弟法
双亲表示法:data是数据域,parent是指针域
根据结点找双亲结点的时间复杂度为o(1)
孩子表示法
方案一:统一度
方案二:每个结点指针域的个数等于该结点的度
方案一增加了空指针的浪费,方案二在运算时带来时间上的损耗
是以改进得到如下孩子表示法
孩子兄弟表示法(把一颗复杂的树变成了一颗二叉树)
二叉树
对于只有两种结果的情形,都适合用树状结构来建模
满二叉树
完全二叉树(如果编号为i的结点与同样深度的满二叉树中编号为i的结点在
二叉树中位置完全相同)
二叉树性质:
1、在二叉树的第i层上至多有2i-1个结点
2、深度为k的二叉树至多有2k-1个结点
3、对任何一颗二叉树,如果其终端结点数为n0,
度为2的结点数为n2,则满足:n0=n2+1
4、具有n个结点的完全二叉树的深度为[log2(n)] + 1
其中[x]表示不大于x的最大整数
5、一颗有n个结点的完全二叉树(深度为[log2(n)] + 1)的结点按层编号,对任
一结点i有:
1 如果i=1,则结点是二叉树的根;如果i>1,则其双亲是结点[i/2]
2 如果2i>n,则结点无左孩子,否则其左孩子是结点2i
3 如果2i+1>n,则结点i无有孩子,否则其右孩子是结点2i+1。
二叉树的顺序存储结构(一般只用于完全二叉树)
一颗完全二叉树图示
其顺序存储
二叉链表
结点结构图
遍历二叉树
前序遍历:ABDGHCEIF
中序遍历:GDHBAEICF
后序遍历:GHDBIEFCA
层序遍历:ABCDEFGHI
二叉树的前序遍历算法:
二叉树的中序遍历算法
二叉树的后序遍历算法
注意:
已知前序遍历和中序遍历,可以唯一确定一颗二叉树
已知后序遍历和中序遍历,可以唯一确定一颗二叉树
但是:已知前序和后序,不能确定唯一一颗二叉树
线索二叉树
将一颗二叉树进行中序遍历后,将所有空指针改为指向前驱和后继结点的示例,
空心箭头实线为前驱,虚线黑箭头为后继
即使改写成这样的双向链表后,依然存在问题,如何区分某一结点的lchild是指向
左孩子还是指向前驱,rchild是指向右孩子还是指向后继(增加0、1标识域)
其中,ltag为0 指向结点的左孩子,为1指向结点的前驱
rtag为0 指向结点的右孩子,为1指向结点的后继
线索二叉树的实现
中序遍历线索化的递归函数代码
二叉树线索链表
二叉线索链表代码(link=0, thread=1)
说明:如果在所用的二叉树需要经常遍历或者查找结点时需要某种遍历序列中的前驱和
后继,那么采用线索二叉链表的存储结构就是非常不错的选择
树、森林与二叉树的转换
树转换为二叉树
示例:
森林转换为二叉树
示例:
二叉树转换为树
1、加线。若某结点的左孩子结点存在,则将这个左孩子的右孩子结点,右孩子的右孩子
结点。右孩子的右孩子的右孩子的结点。。。,反正就是左孩子的n个右孩子结点都作为
此结点的孩子。将该结点与这些右孩子结点用线连接起来
2、去线。删除原二叉树中所有结点与其右孩子结点的连线
3、层次调整。使之结构层次分明
示例:
二叉树转换为森林
示例
说明:当以二叉链表作树的存储结构时,树的先根遍历和后根遍历完全可以借用
二叉树的前序遍历和中序遍历的算法来实现。
赫夫曼树