最近看了一本算法入门书——算法图解。
封面的插画很好玩儿。最吸引我的还是封面里的一句话:向小说一样有趣的算法入门书。
上个封面,大家感受一下:
一个有序数组中找一个数的位置(对应该数字所在数组下标index)
def binary_search(list, item):
low = 0
high = len(list) - 1
while low <= high:
mid = int((low + high) / 2)
guess = list[mid]
if guess == item:
return mid
if guess > item:
high = mid - 1
else:
low = mid + 1
return None
my_list = [1, 3, 5, 7, 9]
print(binary_search(my_list, 3)) # => 1
print(binary_search(my_list, -1)) # => None
旅行商前往n个城市,确保旅程最短。求可能的排序:n!种可能。
将数组元素按照从小到大的顺序排序,每次从数组中取出最小值
def findSmallest(arr):
smallest = arr[0]
smallest_index = 0
for i in range(1, len(arr)):
if arr[i] < smallest:
smallest = arr[i]
smallest_index = i
return smallest_index
def selectionSort(arr):
newArr = []
for i in range(len(arr)):
smallest = findSmallest(arr)
newArr.append(arr.pop(smallest))
return newArr
print(selectionSort([5, 3, 6, 2, 10])) #[2, 3, 5, 6, 10]
适用递归的算法要满足:
特点:
还有一种高级一点的递归:
举个简单的例子: 阶乘f(n) = n!
#递归
def fact(x):
if x == 1:
return 1
else:
return x * fact(x-1) #注意这里跟尾递归不同
#尾递归
def factorial(x,result):
if x == 1:
return result
else:
return factorial(x-1,x*result)
if __name__ == '__main__':
print(fact(5)) #5*4*3*2*1 = 120
print(factorial(5,1)) #120
def quicksort(array):
if len(array) < 2:
return array
else:
pivot = array[0]
less = [i for i in array[1:] if i <= pivot]
print(less)
greater = [i for i in array[1:] if i > pivot]
print(greater)
return quicksort(less) + [pivot] + quicksort(greater)
if __name__ == '__main__':
print(quicksort([7,1,10,5,3,2,6]))
def mergeSort(array):
if len(array) < 2:
return array
else:
mid = int(len(array)/2)
left = mergeSort(array[:mid])
right = mergeSort(array[mid:])
return merge(left, right)
def merge(left, right): #并两个已排序好的列表,产生一个新的已排序好的列表
result = [] # 新的已排序好的列表
i = 0 # 下标
j = 0
# 对两个列表中的元素 两两对比
# 将最小的元素,放到result中,并对当前列表下标加1
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
# 此时left或者right其中一个已经添加完毕,剩下的就全部加到result后面即可
result += left[i:]
result += right[j:]
return result
array = [9,5,3,0,6,2,7,1,4,8]
result = mergeSort(array)
print('排序后:',result) #排序后: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
归并排序时间复杂度是O(nlogn)
最坏情况也是O(nlogn)
归并排序采用先分后总的方式,先按中间分,分到数组最后只有一个元素为止,最后两两合并。有点mapReduce的味道。
#冒泡排序,每次寻找最小到元素往前排,就像汽水从下往上冒一样。所以叫冒泡排序
def simpleSort(array):
for i in range(len(array)-1):
for j in range(i,len(array)):
if array[i] > array[j]:
temp = array[i]
array[i] = array[j]
array[j] = temp
return array
print(simpleSort([9,8,6,7,4,5,3,11,2]))