数据结构和算法(一)

     学习的曲线总是曲折式前进,所以我记下当前对于算法和数据结构的一些心得,期待以后获得更高层次的理解之后,再来更新这一系列。

     要掌握好基本的数据结构和算法,首先我们要对这些基本的数据结构和算法的应用背景非常了解,这样才能深入的理解它们可以做什么,为什么可以这么做,优点是什么,缺陷是什么。才算是基本掌握了数据结构和算法。等到再去磨练磨练熟练度,理解也会越来越深入,对它们的本质也会了然于胸。

     举个例子,如果给定这样一个应用场景:如何在一本字典里查找一个单词。大家能够快速反应出的算法是什么呢?我想比较靠谱的思路应该是这样:字典里单词的数量级不是很大,数据的存储是静态的,操作只需要一个查找。那么如果对这些已知条件都掌握以后,又像上面说的那样掌握了各个算法,就可以知道应该使用的是二分查找。

     下面就依照这个思路去整理各个基本数据结构和算法。

第一部分: 查找

 

1.顺序查找:

使用环境:

     在一个未知是否有序的集合中频繁查找元素,这个集合可能支持索引,如同数组那样,也可能只能通过一个迭代器来访问集合的下一个元素。除此以外,没有任何关于集合的信息。此时,你只能通过这个索引或迭代器顺序的查找这个集合。很简单,也很好理解。

变种:

      如果你知道一些目标元素的信息,可能有一些策略来改善顺序查找的性能,这些策略仅是抛砖引玉的作用:

          成功查找到则将它移动到最前面

               这个策略适用于:查找到的元素在以后有更大的概率再次被查找到。也是操作系 统里最近最多使用算法(MRU)的基础。

          成功查找则移动到最后

               这个策略适用于:所有元素要以等概率被查找到。

 

2.二分查找

使用环境:

      二分查找对大的集合查找很快,但是它需要一个有序集合,并且要求集合是静态的,如果要从集合中添加和删除元素,二分查找就变得很笨拙。

变种:

     二分查找有两个主要的变种。都是和处理动态数据有关,要求不光有一个比较好的查找性能,还要能高效的插入和删除元素。

     如果集合能够存储在内存里,那么一个好的方法是使用散列表,另外一个方法是在内存里构建一个二叉查找树。一般有AVL树和红黑树。

 

3.散列表

使用环境:

     查找比较大的集合,并且不需要数据有序。散列表可以处理动态集合,来一个数据,散列之,扔桶里。

性能:

      散列表的性能跟散列函数和碰撞处理规则有关。散列函数越能将原数据集均匀分布到桶里,性能越好。碰撞处理一般使用链表。

变种:

     一个主要变种是修改了碰撞处理的规则。使用一种开放定址技术。

 

4.二叉查找树:

使用环境:

     以下三种环境可能会促使我们选择二叉查找树:

  • 集合的大小未知,而程序要求处理任何规模的数据。
  • 集合是高度动态的,在程序运行时有大量的插入和删除操作。
  • 程序需要按照升序或降序来遍历元素。

而一旦我们决定使用二叉树,如果数据是动态的,我们必须要平衡树。否则经过多次的插入删除后,二叉树就接近于链表了。

posted on 2013-03-28 20:57  书上一缕香  阅读(164)  评论(0)    收藏  举报

导航