数据结构和算法总览

数据结构和算法总览

一。大部分问题抽象其数据类型,可分为三种。

抽象出3种数据模型,并研究这3种模型的存储及常用操作,对于解决问题有很大帮助。而且有个重要一点就是让程序员交流起来更顺畅,代码都是推荐的那个套路,减低bug和提高效率。

1.线性关系(可表示1对1关系模型, 天然存在于数据本身就是一个挨一个这种类型。如一个班学生按学号排位)

2.树型关系,常见二叉平衡二叉(表示1对多关系,天然存在于树型层级的关系,或适合对半分的情况,如学生会分级管理, 地区分级,公司分级,成绩分级)

3.图关系(表示多对多关系,天然存在于相对独立,分散的关系,如学生们之间的关系,城市间关系,)

逻辑上模型有3种,数据的存储一般是3种,顺序存储和链表存储,还有一个hash  .

在队列逻辑数据结构中,一般队列和环形缓冲这2中队列,体现了对存储天生的需求不同,非常经典,一般队列,选用链表,方便删除和添加,而环形队列,因为固定大小选用顺序存储,方便读起,

 

二。大部分问题归纳其解决思路,大致分为分治,贪心,动态,回溯等思路,即算法。

解决问题,也就是算法实现的过程,需要通过数据结构来实现。二者是再一起的,根据问题,选择一个合适的数据结构,再选择一个算法。就是这样,喵。

面对一个问题如何分析?自己总结最灵魂的一句话就是如何找出同样形式和性质的小问题,分治,贪心,动态,无不包含此目标。

总体思路,先把问题特例化,极简化,简化到心算就可以求解。再慢慢扩大规模,试图发现规律。大概知道规律后,先尝试分治法,因为分治有递归好基友帮忙,好实现,又好理解。

还有一种就是每步都是最优解,期望最后是最优解,就是贪心。

如果每一步最优,不能导致结果最优(一般可以通过反证法,或者举个例子)。而是需要知道所有解才行的问题,那么也可以先尝试解答最小解,并记录,避免上层重复求解子问题。这就是动态表格法,就是动态算法。

 

分治:

如果一个问题很小,很简单,那么一般解决操作也会很简单。也就没有研究的价值,所以一般需要研究的是问题规模比较大,所以才需要研究。

那么很自然,算法的目标就是发现规律,把大问题分解为同样形式和性质小问题,并组合起来。这种自然的思路就是分治

分治含有2个注意点:

1,divide和combine 分解和组合,   原问题分解为同质的小问题的组合(X=X1+X2+a),X,无法由具体的操作表示。 a,某个具体的操作

2.  comquer 解决  Xn=b+c   ,    最后问题减少规模到某个阀值,可以表示为某些具体操作。

所以最终问题都变成了具体操作的组合。 X=((b+c)+(b+c)+a)+........................

 

贪心和动态:

除了分治,还有一个思路就是试探性的做出一步。典型就是贪心,

选择当前问题下的一个最优解,删除此解,并更新下上文(删除这个解所带来的变化)来减少规模,新问题必须和老问题是同一性质的问题,并且是最优解的子结构。只是规模变小了。重复上面步骤,直到问题规模变为0,全部解答。

比如多活动需要抢某一个场地,如何在某个时间段,安排最多的活动:  选择一个最早结束的活动,作为最优解,更新时间段,和留下有效的活动。重复步骤。

但是必须证明贪心法,会导致最终是一个最优解。一般可以通过反证法,或者举个具体例子,就可以发现是否适合贪心法。

如切钢条,一个长钢条,切成不同段,价格不一样,如何切除最贵的。

如果按照贪心算法,选择性价比最优的段来切,切完再找性价比最优的来切,看起来会得到最优解,但是切了一个大的,可能剩下的只能切个性价比最差的。还不如切几个性价比中等的,更好。

所以有时候贪心算法只能得到一个次优解,问题出在:

选择当前问题下的一个最优解,删除此解,并更新下上文(删除这个解所带来的变化)来减少规模,新问题必须和老问题是同一性质的问题,并且子解是最优解的一部分,但有时候不是。

所以可能需要把所有解全部算出来,才能知道最优解。不能像贪心一样,做一步子解,就已经是最优解的子解。

但是可以先贪心,如果发现做一步最优子解,可以证明子解是最优解的一部分,那么就是贪心,      

如果发现做一个最优子解,不会最优解的一部分,那么就需要考虑用动态算法了。

动态算法,算出所有解,但是也有技巧,需要一步一步保存子解的值,来节省算法时间。

 

 

基本上就是分治和贪心这两种大思路,

 

 

综合,

思路是2种,分治和贪心

算法基本核心就1个:分解问题。

从大直接分割为几个小部分有:分治的快排法

从小部分组合为整体有:分治的归并法

从小往大一层一层独立推进有 ,分治的汗罗塔的递归法

从大往小,一层一层缩小有:贪心法的活动安排问题。

从小往大,一层一层利用之前的解有:动态规划法的锯钢条,

 

 

还有常见的算法处理的一类排列组合的问题。

还有一些必须穷举的,在穷举的基础上进行优化,就是回溯思路

还有一写问题和规模无关,比如随机算法。

还有一种我把它叫做创造力算法,比如等差级数之和,按照常规递归思路或缩小问题规模,那么就是一般的一个一个累加,但是如果有相应知识和创造力思维,能吧一个大规模问题,突然变成另外一个规模很小的问题,如加法变成乘法。

那就牛了。想想高斯,一年级就会乘法了,他不但牛在创造,也在于自学厉害,1年级自学了乘法,并会灵活运行。放到现实生活中,如果你发明了一个没人知道的乘法,把它用在大家知道的加法上。你说牛不牛!!!!!!!!!牛到暴躁。

 

树的最优二叉树即哈夫曼树(Huffman Tree)看起来很简单,但没想出来没关系,霍夫曼本人是博士,而且是经过了一个学期才完成,而且还看了Shannon-Fano,及次优Shannon-Fano的树

 

算法总结:

1.分治

2.贪心

3.动态规划

4.排列组合

5,深度优先和回溯

数据结构:

1.线性

2.1对多

3.多对多

 

 

值得复习的:

快排和归并排序(线性结构数组+分治+递归)

二叉树,以及平衡二叉树(树结构+递归)

最短距离(图+动态)

切钢条(图+动态)

值得复习,但复杂点的:

kmp

rbt

堆排

 

posted @ 2018-12-30 01:58  琴鸟  阅读(412)  评论(2)    收藏  举报