日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

python自动开发之(算法)第二十七天

發(fā)布時(shí)間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python自动开发之(算法)第二十七天 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

1、什么是算法?

算法(Algorithm):一個(gè)計(jì)算過程,解決問題的方法

2、復(fù)習(xí):遞歸

遞歸的兩個(gè)特點(diǎn):(1) 調(diào)用自身 (2)結(jié)束條件

def func1(x):print(x)func1(x-1)def func2(x):if x>0:print(x)func2(x+1)def func3(x):if x>0:print(x)func3(x-1)def func4(x):if x>0:func4(x-1)print(x)
View Code

func1和func2不是遞歸

func3和func4是遞歸,但是結(jié)果不一樣,func3(5)打印的是5,4,3,2,1?而func4(5)結(jié)果是1,2,3,4,5

3、時(shí)間復(fù)雜度

時(shí)間復(fù)雜度:用來評估算法運(yùn)行效率的一個(gè)東西

小結(jié):

  時(shí)間復(fù)雜度是用來估計(jì)算法運(yùn)行時(shí)間的一個(gè)式子(單位)。

  一般來說,時(shí)間復(fù)雜度高的算法比復(fù)雜度低的算法快。

  常見的時(shí)間復(fù)雜度(按效率排序)

  O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(nlogn)<O(n^3)

  不常見的時(shí)間復(fù)雜度(看看就好)

  O(n!) O(2n) O(nn) …

  如何一眼判斷時(shí)間復(fù)雜度?

  循環(huán)減半的過程?O(logn)

  幾次循環(huán)就是n的幾次方的復(fù)雜度

?4、空間復(fù)雜度

  空間復(fù)雜度:用來評估算法內(nèi)存占用大小的一個(gè)式子

5、列表查找

  列表查找:從列表中查找指定元素

  輸入:列表、待查找元素

  輸出:元素下標(biāo)或未查找到元素

6、順序查找

   從列表第一個(gè)元素開始,順序進(jìn)行搜索,直到找到為止。

7、二分查找

  從有序列表的候選區(qū)data[0:n]開始,通過對待查找的值與候選區(qū)中間值的比較,可以使候選區(qū)減少一半。

def bin_search(data_set,val):'''mid:下標(biāo)low:每次循環(huán)的列表最左邊下標(biāo)high:每次循環(huán)的列表最右邊下標(biāo):param data_set:列表:param val: 要找的值:return:'''low = 0high = len(data_set)-1while low <= high:mid = (low+high)//2if data_set[mid] == val:return midelif data_set[mid] > val:high = mid - 1else:low = mid + 1return
View Code

8、列表排序

  將無序列表變?yōu)橛行蛄斜?/p>

  應(yīng)用場景: 各種榜單 各種表格 給二分查找用?給其他算法用

  輸入:無序列表

  輸出:有序列表

9、排序中比較慢的三種: 冒泡排序 選擇排序 插入排序

  ?快速排序

  ?排序NB二人組: 堆排序 歸并排序

? ? ?沒什么人用的排序: 基數(shù)排序 希爾排序 桶排序

  算法關(guān)鍵點(diǎn): 有序區(qū) 無序區(qū)

10、冒泡排序

  首先,列表每兩個(gè)相鄰的數(shù),如果前邊的比后邊的大,那么交換這兩個(gè)數(shù)

  n = len(list),循環(huán)了i趟(i=n-1),第i趟循環(huán)比較了(j = n-i-1 )次,j是每趟循環(huán)比較的次數(shù) 

import random,time#裝飾器
def cal_time(func):def wrapper(*args,**kwargs):t1 = time.time()ret = func(*args,**kwargs)t2 = time.time()print('time cost: %s \r\nfunc from %s'%(t2-t1,func.__name__))return funcreturn wrapper@cal_time
def bubble_sort(li):for i in range(len(li) - 1):for j in range(len(li) - i - 1):#升續(xù)if li[j] > li[j+1]:li[j],li[j+1]=li[j+1],li[j]#降續(xù)# if li[j] < li[j+1]:#     li[j],li[j+1]=li[j+1],li[j]
data = list(range(1000))
random.shuffle(data)
print(data)
bubble_sort(data)
print(data)
View Code

  優(yōu)化后的冒泡排序:

    如果冒泡排序中執(zhí)行一趟而沒有交換,則列表已經(jīng)是有序狀態(tài),可以直接結(jié)束算法。

import random,time#裝飾器
def cal_time(func):def wrapper(*args,**kwargs):t1 = time.time()ret = func(*args,**kwargs)t2 = time.time()print('time cost: %s \r\nfunc from %s'%(t2-t1,func.__name__))return funcreturn wrapper@cal_time
def bubble_sort(li):for i in range(len(li) - 1):exchange = Falsefor j in range(len(li) - i - 1):#升續(xù)if li[j] > li[j+1]:li[j],li[j+1]=li[j+1],li[j]exchange = True#降續(xù)# if li[j] < li[j+1]:#     li[j],li[j+1]=li[j+1],li[j]#     exchange = True#這里是指上一趟,值之間沒有發(fā)生交換,就退出循環(huán)if not exchange:breakdata = list(range(1000))
random.shuffle(data)
print(data)
bubble_sort(data)
print(data)
View Code

11、選擇排序

  一趟遍歷記錄最小的數(shù),放到第一個(gè)位置; 再一趟遍歷記錄剩余列表中最小的數(shù),繼續(xù)放置;

import random,time#裝飾器
def cal_time(func):def wrapper(*args,**kwargs):t1 = time.time()ret = func(*args,**kwargs)t2 = time.time()print('time cost: %s --> \nfunc from %s'%(t2-t1,func.__name__))return funcreturn wrapper@cal_time
def select_sort(li):for i in range(len(li)-1):min_loc = ifor j in range(i+1,len(li)):if li[j] < li[min_loc]:min_loc = jli[i],li[min_loc] = li[min_loc],li[i]
View Code

12、插入排序

def insert_sort(li):for i in range(1,len(li)):tmp = li[i]j = i - 1while j >= 0 and tmp < li[j]:li[j + 1] = li[j]j -= 1li[j + 1] = tmp
View Code

13、練習(xí) 用冒泡法把打亂的帶ID的信息表排序

import randomdef random_list(n):ids = range(1000,1000+n)result = []a1 = ["","","","","","",""]a2 = ["","","","","","",""]a3 = ["強(qiáng)","","","","","",""]for i in range(n):age = random.randint(16,38)id = ids[i]name = '%s%s%s'%(random.choice(a1),random.choice(a2),random.choice(a3))dic = {}dic['id'] = iddic['姓名'] = namedic['年齡'] = ageresult.append(dic)return resultdef bubble_sort(li):for i in range(len(li)-1):for j in range(len(li)-i-1):if li[j]['id'] > li[j+1]['id']:li[j],li[j+1] = li[j+1],li[j]data1 = random_list(100)
random.shuffle(data1)
print(data1)
bubble_sort(data1)
print(data1)
View Code

14、快速排序:快

  好寫的排序算法里最快的

  快的排序算法里最好寫的  

? ? ?快排思路:

    取一個(gè)元素p(第一個(gè)元素),使元素p歸位;

    列表被p分成兩部分,左邊都比p小,右邊都比p大;

    遞歸完成排序。

#快排的復(fù)雜度是O(nlog(n)),這是一個(gè)特殊情況 
#口訣 右手左手一個(gè)慢動作,右手左手慢動作重播(遞歸)
import time,random,copydef cal_time(func):def wrapper(*args,**kwargs):t1 = time.time()ret = func(*args,**kwargs)t2 = time.time()print('time cost: %s from %s'%(t2-t1,func.__name__))return funcreturn wrapperdef quick_sort_x(data,left,right):#這里的left和right是定義列表data,最少有兩個(gè)元素if left<right:#partition分割函數(shù),mid是放好的元素的下標(biāo)mid = partition(data,left,right)#以下類似二分quick_sort_x(data,left,mid-1)quick_sort_x(data,mid+1,right)#快排的復(fù)雜度是O(nlog(n)),這是一個(gè)特殊情況
def partition(data,left,right):#獲取左邊的第一個(gè)元素,這里寫left不能寫零,因?yàn)楹竺嫘枰f歸tmp = data[left]#終止條件為當(dāng)left和right碰上時(shí),所以左小于右時(shí)為while循環(huán)的條件(left和right是下標(biāo))while left < right:#循環(huán)條件是右邊比tmp大,直到找到右邊比tmp小的數(shù),停止循環(huán)while left < right and data[right] >= tmp:right -= 1#把找到的右邊比tmp小的數(shù)移到左邊空出來的位置data[left] = data[right]#循環(huán)條件是左邊比tmp小,繼續(xù)循環(huán),直到找到左邊比tmp大的數(shù),結(jié)束循環(huán)while left < right and data[left] <= tmp:left += 1#把左邊找到的大于tmp的數(shù)移到右邊空出來的位置data[right] = data[left]#當(dāng)左右相等時(shí),就把tmp放到left和right碰到的位置data[left] = tmp#mid的值和lef或right值相同,return哪個(gè)都可以#mid = left# return midreturn left#對遞歸函數(shù)的裝飾,需要再封裝一層
@cal_time
def quik_sort(data):#0及是left,len(data)-1為rightreturn quick_sort_x(data,0,len(data)-1)
View Code
import time,random,copydef cal_time(func):def wrapper(*args,**kwargs):t1 = time.time()ret = func(*args,**kwargs)t2 = time.time()print('time cost: %s from %s'%(t2-t1,func.__name__))return funcreturn wrapperdef quick_sort_x(data,left,right):#這里的left和right是定義列表data,最少有兩個(gè)元素if left<right:#partition分割函數(shù),mid是放好的元素的下標(biāo)mid = partition(data,left,right)#以下類似二分quick_sort_x(data,left,mid-1)quick_sort_x(data,mid+1,right)#快排的復(fù)雜度是O(nlog(n)),這是一個(gè)特殊情況
def partition(data,left,right):#獲取左邊的第一個(gè)元素,這里寫left不能寫零,因?yàn)楹竺嫘枰f歸tmp = data[left]#終止條件為當(dāng)left和right碰上時(shí),所以左小于右時(shí)為while循環(huán)的條件(left和right是下標(biāo))while left < right:#循環(huán)條件是右邊比tmp大,直到找到右邊比tmp小的數(shù),停止循環(huán)while left < right and data[right] >= tmp:right -= 1#把找到的右邊比tmp小的數(shù)移到左邊空出來的位置data[left] = data[right]#循環(huán)條件是左邊比tmp小,繼續(xù)循環(huán),直到找到左邊比tmp大的數(shù),結(jié)束循環(huán)while left < right and data[left] <= tmp:left += 1#把左邊找到的大于tmp的數(shù)移到右邊空出來的位置data[right] = data[left]#當(dāng)左右相等時(shí),就把tmp放到left和right碰到的位置data[left] = tmp#mid的值和lef或right值相同,return哪個(gè)都可以#mid = left# return midreturn left#對遞歸函數(shù)的裝飾,需要再封裝一層
@cal_time
def quik_sort(data):#0及是left,len(data)-1為rightreturn quick_sort_x(data,0,len(data)-1)#冒泡排序
@cal_time
def bubble_sort(li):for i in range(len(li) - 1):exchange = Falsefor j in range(len(li) - i - 1):#升續(xù)if li[j] > li[j+1]:li[j],li[j+1]=li[j+1],li[j]exchange = True#降續(xù)# if li[j] < li[j+1]:#     li[j],li[j+1]=li[j+1],li[j]#     exchange = True#這里是指上一趟,值之間沒有發(fā)生交換,就退出循環(huán)if not exchange:breakdata = list(range(5000))
random.shuffle(data)
#深度拷貝
data1 = copy.deepcopy(data)
data2 = copy.deepcopy(data)#快排和冒泡的比較
quik_sort(data1)
bubble_sort(data2)
print(data1)
View Code

升續(xù):

降續(xù):

?

排序速度的定義:

?

一般情況下快排比冒泡快,快排有遞歸深度的問題,如果深度高的話,需要調(diào)整。

?15、堆排序

(1)樹與二叉樹簡介

  樹是一種數(shù)據(jù)結(jié)構(gòu)?比如:目錄結(jié)構(gòu)

  樹是一種可以遞歸定義的數(shù)據(jù)結(jié)構(gòu)

  樹是由n個(gè)節(jié)點(diǎn)組成的集合:

    如果n=0,那這是一棵空樹;

    如果n>0,那存在1個(gè)節(jié)點(diǎn)作為樹的根節(jié)點(diǎn),其他節(jié)點(diǎn)可以分為m個(gè)集合,每個(gè)集合本身又是一棵樹。

  一些概念

    根節(jié)點(diǎn)、葉子節(jié)點(diǎn)

    樹的深度(高度)

    樹的度

    孩子節(jié)點(diǎn)/父節(jié)點(diǎn) 子樹

  

(2)二叉樹

  二叉樹:度不超過2的樹(節(jié)點(diǎn)最多有兩個(gè)叉)

?  

(3)滿二叉樹,完全二叉樹

?(4)二叉樹的存儲方式

  鏈?zhǔn)酱鎯Ψ绞?/p>

  順序存儲方式(列表)

  

  父節(jié)點(diǎn)和左孩子節(jié)點(diǎn)的編號下標(biāo)有什么關(guān)系?

  0-1 1-3 2-5 3-7 4-9

  i ~ 2i+1

?

  父節(jié)點(diǎn)和右孩子節(jié)點(diǎn)的編號下標(biāo)有什么關(guān)系?

  0-2 1-4 2-6 3-8 4-10

  i ~ 2i+2

(5)小結(jié)

  二叉樹是度不超過2的樹

  滿二叉樹與完全二叉樹

  (完全)二叉樹可以用列表來存儲,通過規(guī)律可以從父親找到孩子或從孩子找到父親

(6)堆排序

  大根堆:一棵完全二叉樹,滿足任一節(jié)點(diǎn)都比其孩子節(jié)點(diǎn)大

  小根堆:一棵完全二叉樹,滿足任一節(jié)點(diǎn)都比其孩子節(jié)點(diǎn)小

(7)堆排序過程

  a、建立堆

  b、得到堆頂元素,為最大元素

  c、去掉堆頂,將堆最后一個(gè)元素放到堆頂,此時(shí)可通過一次調(diào)整重新使堆有序。

  d、堆頂元素為第二大元素。

  e、 重復(fù)步驟3,直到堆變空。

  

?

轉(zhuǎn)載于:https://www.cnblogs.com/willpower-chen/p/6510388.html

總結(jié)

以上是生活随笔為你收集整理的python自动开发之(算法)第二十七天的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。