一、什么是算法?
- 算法有高效的,也有拙劣的,好的算法能够达到四两拨千斤的效果,但差的算法会消耗大量的内存和运行时间。效果相差甚远。
- 算法可以应用在以下场景:
1、运算 2、查找 3、排序 4、最优决策
二、数据结构
- 数据结构是算法的基石,有以下几类:
– 线性结构:如数组、链表
– 树:如二叉树、二叉堆
– 图:复杂数据结构,在图中呈现多对多的关联关系。
– 其他
数组的特点:
- 最简单、最常用的数据结构,在内存中顺序存储,通过下标即可实现读操作,但是不易增删。适合用于多读少写的操作场景,例如二分查找。
- 插入元素:尾部插入,中间插入,超范围插入(需要扩容,创建一个新的数组再复制旧数组)
- 删除元素:将删除位点及以后的元素依次向前赋值进行覆盖。
- 数组的插入和删除操作复杂度都是O(n)
链表的特点:
- 在内存中随机存储,占用内存中的不同位置,依靠next指针进行关联。
- 链表中的数据只能顺序访问,最坏时间复杂度为O(n)
- 插入节点:尾部插入、头部插入、尾部插入,只需要改变next指针的指向就可以轻松完成。删除元素同理,复杂度都为O(1)。
- 适用于少读多写的情况。
三、物理结构和逻辑结构:
- 数组和链表称为物理结构,逻辑结构是抽象概念,依赖于物理结构而存在在。
- 逻辑结构 线性结构(顺序表、栈、队列)、非线性结构(树、图)
- 物理结构 顺序存储结构(数组等) 链式存储结构(链表等)
四、逻辑结构
栈:如圆筒里放的羽毛球,先入后出。
- 基本操作:入栈(push),出栈(pop)
- 应用:历史回溯,如浏览器返回上一级页面。
队列:隧道行车,先入先出。
- 基本操作:入队(enqueue)、出队(dequeue)
- 应用:如爬虫依次爬取队列中url。
散列表(哈希表):
- 提供了键值对,通过哈希函数将键转变为下标,如果下标重复则开放寻址或者链表法存储。读写操作复杂度都为O(1).
- 为了提升效率,JDK8中HashMap采用了红黑树的方法来存储冲突下标的元素。
树:
- 二叉树(每个节点最多有两个孩子节点)
- 满二叉树,完全二叉树。
- 可以采用链式存储或者数组的物理结构来表达。
- 链式存储中使用左右指针表示父子节点的关系,数组中采用存储位置来表示,如果缺失左右孩子节点则空出该位置。父节点下标为parent,则左孩子节点下标为2parent+1,右孩子为2parent+2
- 应用:易于查找和维持相对顺序。
- 二叉树的自平衡:红黑树、AVL树、树堆等。
- 遍历:由于不是链式结构所以遍历有复杂性。
- 有深度优先:前序遍历、中序遍历、后序遍历。采用递归的方式。也可利用栈来进行遍历。
- 广度优先:
二叉堆
- 最大堆、最小堆。
- 插入节点、删除节点,需要根据大小比较进行上浮、下沉操作。时间复杂度都是O(logn)