由于某些机缘巧合的原因,最近重新开始学习算法,学习那二十年前的我最喜欢,而却又抛弃了的东西。虽然现在已不能全心全意埋头苦学,也没有了当年灵光的头脑和意气风发的精神面貌,但却可细水长流,慢慢品尝。岁月就像那深藏的红酒,越品越醇。
一、排序与查找
快速排序(quick sort):
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
def quicksort(arr): if len(arr)<=1: return arr else: pivot=arr[0] less=[i for i in arr[1:] if i<=pivot] greater=[i for i in arr[1:] if i>pivot] return quicksort(less)+[pivot]+quicksort(greater)
二分查找(binary search):
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
def binarySearch(arr,n):
print("========== Search %s in %s =========="%(n,arr))
if arr==None or len(arr)==0: return None
arrLen=len(arr)
min=0
max=arrLen-1
mid=int(arrLen/2)
while mid>=0 and mid<=arrLen-1:
pivot=arr[mid]
if n==pivot:
return mid
elif max==0 or min==arrLen-1:
return None
elif n<pivot:
max=mid
mid=int((min+max)/2)
elif n>pivot:
min=mid
mid=int((min+max+1)/2)
return None
二、搜索
广度优先搜索(breadth-first search,BFS):
在广度优先搜索算法中,解答树上结点的扩展是按它们在树中的层次进行的。首先生成第一层结点,同时检查目标结点是否在所生成的结点中,如果不在,则将所有的第一层结点逐一扩展,得到第二层结点,并检查第二层结点是否包含目标结点,……,对层次为 n+1 的任一结点进行扩展之前,必须先考虑完层次为 n 的结点的每种可能的状态。因此,对于同一层结点来说,求解问题的价值是相同的,可以按任意顺序来扩展它们。通常采用的原则是先生成的结点先扩展。
为了便于进行搜索,要设置一个表存储所有的结点。由于在广度优先搜索算法中,要满足先生成的结点先扩展的原则,所以存储结点的表一般采用队列这种数据结构。
广度优先搜索算法的搜索步骤一般是:
(1)从队列头取出一个结点,检查它按照扩展规则是否能够扩展,如果能则产生一个新结点。
(2)检查新生成的结点,看它是否已在队列中存在,如果新结点已经在队列中出现过,就放弃这个结点,然后回到第(1)步。否则,如果新结点未曾在队列中出现过,则将它加入到队列尾。
(3)检查新结点是否目标结点。如果新结点是目标结点,则搜索成功,程序结束;若新结点不是目标结点,则回到第(1)步,再从队列头取出结点进行扩展。
最终可能产生两种结果:找到目标结点,或扩展完所有结点而没有找到目标结点。
如果目标结点存在于解答树的有限层上,广度优先搜索算法一定能保证找到一条通向它的最佳路径,因此广度优先搜索算法特别适用于只需求出最优解的问题。当问题需要给出解的路径,则要保存每个结点的来源,也就是它是从哪一个节点扩展来的。