算法图解学习笔记

花了一个周左右时间大致看完了《算法图解》这本书。总体来讲,这书还不错,深入浅出地介绍了一些常见的算法。对我这种非计算机科班出身的人学习算法起到了入门和引路的作用。以下是自己学完之后的一点小总结。如有不对还请大家指正。

一、算法简介

1.大O表示法可以用来表示一种算法的时间复杂度。经常遇到的5种大O运行时间

O(logn) 对数时间,包括二分查找

O(n)线性时间,包括简单查找

O(nlogn) 快速排序

O(n2)选择排序

O(n!)旅行商问题

二、选择排序

1.数组和链表是常用的两种数据结构,数组在内存空间中是连续存储,而链表是不连续存储,所以数组查找快,增删慢。而链表由于每个元素中有都指向它前后元素的指针,因此增删快查找慢。

2.选择排序本身,光看书上的例子,还不是很理解。有点类似于人工排序,比如给考试成绩进行排序,当学生数目不多时,完全可以人脑(人工)排序,先将其所有内容遍历一遍,把最小的或最大的挑出来排在第一位,然后在剩余的内容中去找第二小或第二大的内容,以此类推,感觉在比较过程中还是隐含了类似冒泡排序的思想,否则怎么看出(挑出)最小/最大值的?

三、递归

1.递归的关键在于搞清楚基线条件和关键条件,所谓基线条件就是在什么条件下不递归了,直接能给出一个确定的值或者结果(比如阶乘时,传递的参数为1时,或者要对数组中的数字进行排序时,数组中的元素个数为1的情况),除此之外,不满足基线条件的情况下,就是递归条件,递归条件在写的时候一般是用一个表达式或者什么因子作用于另一个式子,而另一个式子中就需要调用到递归函数本身,只是在调用时里面传递的参数发生了变化,比如原来是n,现在是n-1.最典型的递归就是求阶乘了,还有一个就是汉诺塔问题,几乎各种编程语言在讲递归算法时都会用到这两个例子。

2.递归是靠调用栈来实现的,有的时候,一个问题可以用递归,也可以用for/while循环来解决,那到底是选择用递归还是循环呢?递归的好处是便于人理解,但它是靠调用栈来实现,所以如果递归次数过多,比较消耗栈资源。而循环写出的程序可能有时候可读性没有那么强,但是相对而言会节省空间资源一些。到底选哪个,一方面是看具体问题,另一方面就是看个人喜好了。

3.栈

栈的操作分压栈和弹出。它的规则是先进后出(FILO).数据的存入叫做压栈,读取叫弹出。所有函数的调用都进入调用栈

四、快速排序

1.本章的重点是使用学到的新技能来解决问题。我们将探索分而治之( divide and conquer, D&C) ——一种著名的递归式问题解决方法。分而治之就是将大的复杂问题分成模块化的小问题,再各个击破。本节中的例子是分田地问题,先将不规则的长宽分成一块容易分的大块“规则”土地,和一块小的不规则土地,然后再从小的不规则土地中再分出一块尽可能大的规则土地,以此循环,直到结束……

2.快速排序的思想也是分而治之,对于一个数组,先选一个元素当作基准值,然后把比它小的元素放左边,比它大的元素放右边,再分别在左边和右边做同样类似的操作,直到某一个元素,比它小的只有一个值,另一个元素比它大的也只有一个值为止。

3.快速排序时应随机选择基准值,快速排序的平均运行时间为O(n log n)。

4.用大O表示法来表示时间复杂度时,里面的常量有时候无关紧要,有时候又至关重要,我认为当O()里面的表达式数量级差不多时就比较重要,数量级相差太多时常数C就可以忽略

五、散列表

散列表就是哈希表的另一种翻译,它们都是Hash table。

猜你喜欢

转载自www.cnblogs.com/flyingtester/p/12240983.html