算法入门
列表查询
递归

def func1(n): if n > 0: print(n) func1(n-1) func1(4) def func2(n): if n > 0: func2(n - 1) print(n) func2(4) def text(n): if n > 0 : print("抱着",end='') text(n-1) print("的我",end='') else: print("我的小鲤鱼",end='') text(5) #n阶楼梯,F(n),4阶楼梯,1111 112 211 121 22;F(n)斐波那契第n项 # 1 1 2 3 5 8 13 21 登楼梯方法数 # 0 1 2 3 4 5 6 楼梯阶数 #f(1)=1,f(2)=2 # f(n) = f(n-1) + f(n-2);f(n)====n阶楼梯的方法数 #汉诺塔问题 """ n个盘子时: 1、把n-1个园盘从A经过C移动到B 2、把第n个圆盘从A移动到C 3、把n-1个小圆盘从B经过A移到C """ def hanoi(n,A,B,C): if n > 0: hanoi(n-1,A,C,B) print('%s-->%s'%(A,C)) hanoi(n-1,B,A,C) num = '' while num != 'b': num = int(input("请输入汉诺塔的层数:")) hanoi(num,"A","B","C")
二分法查询
import time #计算函数运行时间 def cal_time(func): def wrapper(*args,**kwargs): t1 = time.time() result = func(*args,**kwargs) t2 = time.time() print("%s running time: %s secs."%(func.__name__,t2-t1)) return result return wrapper #二分法查找 时间复杂度O(logn) @cal_time def binary_search(li,target): low = 0 hight = len(li) - 1 while low <=hight: mid = (low + hight) // 2 if target >li[mid]: low = mid + 1 elif target < li[mid]: hight = mid - 1 else: return mid else: return None @cal_time def linear_search(li,val): try: i = li.index(val) return i except: return None li = list(range(1000000)) try: print(binary_search(li,56677),len(li)) print(linear_search(li, 56677), len(li)) except Exception as e: print(e)
递归版的二分法
#非递归效率>=递归 #递归存在的价值就是解决只能用递归实现的问题 def bin_search(li,target,low,hight): if low <= hight: mid = (low+hight)//2 if li[mid] == target: return mid elif li[mid] > target: # hight = mid - 1 return bin_search(li,target,low,mid-1)#尾递归(递归总在最后一句调用) elif li[mid] < target: # low = mid + 1 return bin_search(li,target,mid+1,hight) else: return None li = list(range(1000)) print(bin_search(li,222,0,999))
列表排序
冒泡排序

import time #计算函数运行时间 def cal_time(func): def wrapper(*args,**kwargs): t1 = time.time() result = func(*args,**kwargs) t2 = time.time() print("%s running time: %s secs."%(func.__name__,t2-t1)) return result return wrapper #冒泡排序的时间复杂度是O(n^2) @cal_time def bubble_sort(li): for i in range(0,len(li)-1): #i表示趟数,有序区有i个数 for j in range(0,len(li)-1-i):#对无序区进行遍历 if li[j] > li[j+1]: li[j],li[j+1] = li[j+1],li[j] return li #冒泡优化---最好情况下 @cal_time def bubble_sort2(li): for i in range(0,len(li)-1): #i表示趟数,有序区有i个数 exchange = False for j in range(0,len(li)-1-i): if li[j] > li[j+1]: li[j],li[j+1] = li[j+1],li[j] exchange = True if not exchange:#此列表无须排序 return li return li import random li = list(range(10000)) print('-------最好情况下------',bubble_sort2(li)) random.shuffle(li)#将li顺序打乱 print(li) print(bubble_sort(li))
选择排序

#时间复杂度O(n^2) def select_sort(li): for i in range(len(li)-1): #第i趟:有序区li[0:li] 无序区li[i:n] min_loc = i#假定无序区第一个数为无序区的最小数下标 for j in range(i+1,len(li)):#找到无序区最小数的位置 if li[min_loc] > li[j]: min_loc = j li[min_loc],li[i] = li[i],li[min_loc]#将无序区最小数与有序区第i个位置交换 return li li = list(range(10000)) import random random.shuffle(li) print(li) print(select_sort(li))
插入排序

#时间复杂度为O(n^2) def insert_sort(li): for i in range(1,len(li)): #i 为摸牌的第i次,摸牌的下标 j = i-1#j是手上最后一张牌的下标 tmp = li[i]#存储摸到的牌 while j>=0 and tmp < li[j]:#遍历手中的牌 li[j+1] =li[j] j = j-1 else: li[j+1] = tmp return li # li = [10,1,4,9,3,7,5] li = list(range(1,200)) import random random.shuffle(li) print(li) print(insert_sort(li))
快速排序

#归位,时间复杂度为O(n) def partition(li,left,right): tmp = li[left] while left < right: #从右边找比tmp小的数,放到tmp的左边 while left < right and li[right]>=tmp: right -= 1 li[left] = li[right] #从左边找比tmp大的数,放到tmp的右边 while left < right and li[left]<=tmp: left += 1 li[right] = li[left] li[right] = tmp return right #递归排序,时间复杂度,O(logn) def quick_sort(li,left,right): if left < right: mid = partition(li,left,right)#获取归位元素的下标 quick_sort(li,left,mid-1) quick_sort(li,mid+1,right) return li def sys_sort(li):#python内置排序Timsort,时间复杂度O(nlogn) li.sort() return li li = [1,23,2,33,231,2323,11,1,7878,8090] import copy li1 = copy.deepcopy(li) print(quick_sort(li,0,len(li)-1)) print(sys_sort(li1))
Great works are not done by strength, but by persistence!