# 常见的python算法题

## 1.二分法

# -*- coding: utf-8 -*-
def binary_search(list,item):
low = 0
high = len(list)-1

while low<=high:
mid = (low+high)/2
print "中位数%s" %mid
guess = list[mid]
print "中位数的值%s" % guess
print "输入的值%s" % item
if guess>item:
high = mid-1
print "5>3"
elif guess<item:
low = mid+1
print "5<3"
else:
print high
print low
return mid

return None

mylist = [1,3,5,7,9]
print binary_search(mylist,3)
def binarysearch(target,sortedlist):
left = 0
right = len(sortedlist)-1
while left < right:
midpoint = (left+right) // 2
if target == sortedlist[midpoint]:
return midpoint
elif target > sortedlist[midpoint]:
left = midpoint+1
else:
right = midpoint-1

alist = [1,3,5,8,0]
target = 8

print(binarysearch(target, alist))
输出:
3

## 2.选择排序

# -*- coding: utf-8 -*-
#选择排序
#选择排序，主要思想，找到数组中最小的元素，然后往新数组里追加，时间复杂度O(n^2)

def FindSmallest(arr):
print "array now is %s" %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

print FindSmallest([1,3,5,2])

def selectionSore(arr):
newarr = []
for i in range(len(arr)):
#关键点:arr重建,删掉上次得出的,在运行下次取新的arr里面最小的
newarr.append(arr.pop(FindSmallest(arr)))

print newarr

selectionSore([1,3,5,2,4])


def swap(lyst,i,j):
temp = lyst[i]
lyst[i]=lyst[j]
lyst[j]=temp

def selectsort(lyst):
i=0
while i<len(lyst)-1:
minindex = i
j = i+1
while j<len(lyst):
if lyst[j]<lyst[minindex]:
minindex = j
j+=1
if minindex != i:
swap(lyst,i,minindex)
i+=1

## 2.5.冒泡排序

def bubbleSort(lyst):
n = len(lyst)
while n>1:
i = 1
while i<n:
if lyst[i] < lyst[i-1]:
swap(lyst,i,i-1)
i +=1
n -= 1

## 3.快速排序

#快速排序，递归算法 O(nlogn)

# -*- coding: utf-8 -*-
#递归快速排序
def quicksort(list):
if len(list)<2:
return list #基线条件,为空或者只包含一个元素的数组是有序的
midpivot = list[0]#递归条件
lessbeforemidpivot = [i for i in list[1:] if i<=midpivot]#小于基准值的元素组成的子数组
biggeraftermidpivot = [i for i in list[1:] if i > midpivot]#大于基准值的元素组成的子数组
finallylist = quicksort(lessbeforemidpivot)+[midpivot]+quicksort(biggeraftermidpivot)
return finallylist

print quicksort([2,4,6,7,1,2,5])

## 4.广度优先搜索

# -*- coding: utf-8 -*-
#广度优先搜索
from collections import deque
graph = {}
graph["you"] = ["alice",'bob',"calm"]
graph["alice"] = ["peggym"]
graph["bob"] = ["anuj","peggym"]
graph["peggym"] = ["anuj"]
graph["anuj"] = ["peggym"]
# print type(graph)

def person_is_seller(persion):
if "m" in persion:
return True
def search(name):
search_queue = deque()
# print type(search_queue)
search_queue += graph[name]
# print type(search_queue)
# print (search_queue)
searched = []
while search_queue:
person = search_queue.popleft()

if person not in searched:
if person_is_seller(person):
print person+" is a mango seller!"
searched.append(person)

else:
search_queue += graph[person]
searched.append(person)
# print (search_queue)
return False

search("you")

## 4.狄克斯特拉算法

# -*- coding: utf-8 -*-
#狄克斯特拉算法

# 同时存储邻居和前往邻居的开销
graph = {}
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2

graph["a"] = {}
graph["a"]["fin"] = 1

graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5

graph["fin"] = {}

# 从开始处到每个节点的开销散列表
infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity #终点视为无穷大

#存储父节点的散列表
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None

# 记录处理过的节点的数组
processed = []

# 找出开销最低的节点
def find_lowest_cost_node(costs):
lowest_cost = float("inf")
lowest_cost_node = None
for node in costs:#遍历所有节点
cost = costs[node]#获取节点消费
if cost<lowest_cost and node not in processed: #如果当前节点的开销更低而且没被处理过
lowest_cost = cost #就将其视为最低的节点
lowest_cost_node = node
return lowest_cost_node

node = find_lowest_cost_node(costs)#在没处理的节点里面找到开销最小的节点
while node is not None: #节点都处理完之后结束循环
cost = costs[node]  #b的开销2
neighbors = graph[node] #b节点接下来能走到a和fin节点
for n in neighbors.keys():#枚举出b节点接下来能走到的a和fin节点
new_cost = cost+neighbors[n] #新节点的开销等于b节点的开销加上b分别加上后面的a和fin的开销
if costs[n] > new_cost: #如果单独到达a和fin的开销大于从b走的开销
costs[n] = new_cost #就更新到达这一点的开销的为更小的从b走的记录代替直接走到a的原来的记录
parents[n] = node #将a的父节点设为b节点
processed.append(node)
node = find_lowest_cost_node(costs)



## 5.贪婪算法

# -*- coding: utf-8 -*-
#贪婪算法

# 包含需要覆盖的州的列表,用集合表示,不包含重复元素
states_needed = set(["mt","wa","or","id","nv","ut","ca","az"])

#可供选择的广播台清单,用散列表表示
stations = {}
stations["kone"] = set(["id","nv","ut"])
stations["ktwo"] = set(["wa","id","mt"])
stations["kthree"] = set(["or","nv","ca"])
stations["kfour"] = set(["nv","ut"])
stations["kfive"] = set(["ca","az"])

print stations
# 使用一个集合来存储最终的广播台
final_stations = set()

while states_needed:
best_station = None
states_covered = set()#被选中的广播台覆盖的州,遍历完一遍,没有清空states_needed的话就会重走一遍,重置states_covered
# 遍历出每个台覆盖的州
for station, states in stations.items():
print "遍历到的台%s" %station
covered = states_needed & states #看这个台覆盖的州和需要覆盖的州里面重合的
print "这个台覆盖的州和需要覆盖的州里面重合的%s" %covered
if len(covered)>len(states_covered):
print "重合的比上一个包含的states_covered多的时候"
best_station = station
print "上次states_covered为%s" % states_covered
states_covered = covered

print "更新states_covered为%s" %states_covered

states_needed -= states_covered
print "还没覆盖的州%s"%states_needed
print "已经选出的台%s" % best_station

print final_stations

## 6. O(1)时间复杂度实现入栈出栈获得栈中最小元素最大元素

#定义栈结构，根据栈的后进先出特性，增加辅助栈，来存储当前状态下数据栈中的最小、最大元素。
class Stack(object):

def __init__(self):
self.data = []
self.minValue = []
self.maxValue = []

def push(self,data):
self.data.append(data)
if len(self.minValue)==0:
self.minValue.append(data)
else:
if data <= self.minValue[-1]:
self.minValue.append(data)
if len(self.maxValue)==0:
self.maxValue.append(data)
else:
if data>=self.maxValue[-1]:
self.maxValue.append(data)

def pop(self):
if len(self.data)==0:
return None
else:
temp = self.data.pop()
if temp == self.minValue[-1]:
self.minValue.pop()
if temp == self.maxValue[-1]:
self.maxValue.pop()
return temp

def min(self):
if len(self.data)==0:
return None
else:
return self.minValue[-1]

def max(self):
if len(self.data)==0:
return None
else:
return self.maxValue[-1]

def show(self):
print("stack data")
for data in self.data:
print(data)
print("min",self.min())
print("max",self.max())

if __name__ == "__main__":
s = Stack()
s.push(2)
s.push(1)
s.show()
s.push(4)
s.push(3)
s.push(2)
s.show()
s.pop()
s.show()
s.pop()
s.show()