数据结构真的非常重要,不光是为了应付考试,至今觉得数据结构和编译原理没有学得特别好太遗憾了,给自己做个笔记
结合大话数据结构以及天勤2019数据结构计算机考研复习指导
PS:之前学数据结构的时候直接看严蔚敏的觉得太硬核了
第1章 绪论
具体是啥翻书,记录一下常用的
$$
O(1) <= O(log2(n)) <= O(n) <= O(nlog2(n)) <= O(n^2) <= O(n^3) <= O(2^n)
$$
第2章 线性表
线性表
定义:具有相同特性数据元素的一个有限序列,长度为元素个数
存储结构:顺序存储结构(顺序表);链式存储结构(链表)
存储密度:结点值域所占存储量/节点结构所占存储量
1 | 顺序表:存储需要一块连续的存储空间,有随机访问特性,便于查找,可以随机存取以及顺序存取 |
线性表结构定义
最常见的基本结构
1 |
|
顺序表操作
插入元素
1 | 因为顺序表有序 |
删除元素
1 | 找到下表,删(向前移动)就完事了 |
单链表操作
[例1]已知A、B两个含有头结点的递增链表,并成一个元素非递减有序的链表
注:int *&p 定义一个指针引用,既可以改变指针指向的内容,也可以改变指针本身;
int *q 定义一个指针,可以改变指针指向的内容,但无法改变指针本身
1 | //有序自增链表合并(合并后为自增) |
[例2]查找链表中是否存在元素值为x的结点,有的话就删了,返还1,否则返还0
1 | //查找元素值并删除该结点 |
刚开始还是比较容易的,暗自窃喜
双链表操作
1 | //建立双向链表 |
插入和删除没必要详细些,无非就是单链表拆卸转向双链表拆卸,unlink的操作
循环链表的操作
循环链表可以分为循环单链表与循环双链表,有单链表和双链表演变而来
总而言之,尾节点指回头结点就好了(双链表无非就是两个方向都要指)
第七章 排序
直接插入排序
1 |
|
折半插入排序
1 |
|
冒泡排序
1 |
|
快速排序
1 |
|
简单选择排序
1 |
|
二路归并排序
1 |
|
个别算法小结
二叉树非递归后序遍历
其实我个人觉得递归的逻辑很容易理解,想学习用非递归来遍历二叉树的契机是因为一道题目让我不得不学起来,因为非递归后序遍历可以很快找出二叉树中根结点到某结点之间的路径
非递归后序遍历应该是三种遍历中最难的了,可以一步一步来
先列出存储结构代码
1 | typedef struct TreeNode |
我们先解决一下中序的非递归
1 | void InOrderTraversal(BiTree BT) |
中序的逻辑其实不复杂,借助了一个辅助栈,如果发现该点有左结点,就将其压入栈,直到没有发现左节点时弹出,然后还需要检查弹出的这个结点是否有有结点,然后对这个有结点又要找是否有左结点,有的话再次压入栈中,周而复始,不断查询的过程,可能说的有点乱,抱歉,画个图就懂了
然后接下来就是后序的遍历咯
先序遍历顺序:根节点-左孩子-右孩子
后序遍历顺序:左孩子-右孩子-根节点
后序遍历倒过来:根节点-右孩子-左孩子
对比发现,先序和后序(倒)访问顺序只有左孩子和右孩子颠倒了一下
那么我们在先序遍历的时候左右调换,依次压入栈,然后出栈即可获得
1 | void PostOrderTraversal(BiTree BT) |
这个方法空间复杂度确实一般,但我觉得比较好理解,还有另一种思路,等派上用处了再学吧
本文链接: http://woaixiaoyuyu.github.io/2019/03/28/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84-note/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!