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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python实现排序算法_python实现各种排序算法

發(fā)布時(shí)間:2024/10/8 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python实现排序算法_python实现各种排序算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

冒泡排序

"""

分析

1. 算法是一種與語言無關(guān)的東西,更確切地說就算解決問題的思路,就是一個(gè)通用的思想的問題

2. 冒泡算法作為最簡單的一種排序算法,我們的關(guān)注點(diǎn)不應(yīng)該是代碼本身,而應(yīng)該是思想

3. 冒泡排序思想的側(cè)重點(diǎn)有兩點(diǎn):走一趟干到底選出最大的放到右邊;走幾趟能夠把整個(gè)序列都排序完畢

4. 當(dāng)走一趟干到底的時(shí)候考慮的是j的取值, 而不是j+1, 這樣能清晰地知道range的范圍應(yīng)該是什么

5. is_ordered 標(biāo)志位:如果有序列表就不再排序,直接退出

6. 兩個(gè)for循環(huán)的考慮順序:先考慮內(nèi)層循環(huán)的意義,再考慮外層循環(huán)的意義

"""

def bubble_sort(alist):

n = len(alist)

# i 代表的是第幾趟,從1開始,表示第一趟

for i in range(1, n):

is_ordered = True

# j 表示走一趟

for j in range(n-i):

if alist[j] > alist[j+1]:

alist[j], alist[j+1] = alist[j+1], alist[j]

is_ordered = False

if is_ordered:

return

if __name__ == '__main__':

lis = [9, 11, 2, 2, 1, 20, 13]

bubble_sort(lis)

print(lis)

冒泡排序(英語:Bubble Sort)是一種簡單的排序算法。它重復(fù)地遍歷要排序的數(shù)列,一次比較兩個(gè)元素,如果他們的順序錯(cuò)誤就把他們交換過來。遍歷數(shù)列的工作是重復(fù)地進(jìn)行直到?jīng)]有再需要交換,也就是說該數(shù)列已經(jīng)排序完成。這個(gè)算法的名字由來是因?yàn)樵叫〉脑貢?huì)經(jīng)由交換慢慢“浮”到數(shù)列的頂端。

冒泡排序算法的運(yùn)作如下:

比較相鄰的元素。如果第一個(gè)比第二個(gè)大(升序),就交換他們兩個(gè)。

對(duì)每一對(duì)相鄰元素作同樣的工作,從開始第一對(duì)到結(jié)尾的最后一對(duì)。這步做完后,最后的元素會(huì)是最大的數(shù)。

針對(duì)所有的元素重復(fù)以上的步驟,除了最后一個(gè)。

持續(xù)每次對(duì)越來越少的元素重復(fù)上面的步驟,直到?jīng)]有任何一對(duì)數(shù)字需要比較。

選擇排序

"""

分析:

1. 代碼本身不重要,算法思想才是重中之重

2. 選擇排序從概念上把列表分為前后兩部分,前一部分假設(shè)是有序的(借助一些操作它就是有序的,這也是一種思想),后一部分是亂序的

3. 每次從亂序的當(dāng)中選擇出一個(gè)最小值放到前面一部分的最后一個(gè)位置,這里體現(xiàn)了選擇的概念

4. 穩(wěn)定性:考慮這樣一種情況,把列表分為前后兩部分,后一部分是有序的,每次從前面一部分選出一個(gè)最大值放到后面一部分的第一個(gè)位置,

假設(shè)第一個(gè)元素是99,是最大的,中間還有一個(gè)元素99,因?yàn)楹竺娴?9不比前面的大,所以前面的99放到最后,這樣就不穩(wěn)定了

5. 最優(yōu)時(shí)間復(fù)雜度:即使已經(jīng)是有序,還是得拿著前面的元素和后面的一個(gè)一個(gè)地進(jìn)行比較,所以復(fù)雜度是O(n2)

6. 最壞時(shí)間復(fù)雜度: 內(nèi)層循環(huán)是和n有關(guān)的,復(fù)雜度是O(n2)

"""

def select_sort(alist):

"""

選擇排序

:param alist:

:return:

"""

n = len(alist)

for j in range(n-1):

min_index = j

for i in range(j + 1, n):

if alist[min_index] > alist[i]:

min_index = i

if min_index != j:

alist[j], alist[min_index] = alist[min_index], alist[j]

選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續(xù)尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

選擇排序的主要優(yōu)點(diǎn)與數(shù)據(jù)移動(dòng)有關(guān)。如果某個(gè)元素位于正確的最終位置上,則它不會(huì)被移動(dòng)。選擇排序每次交換一對(duì)元素,它們當(dāng)中至少有一個(gè)將被移到其最終位置上,因此對(duì)n個(gè)元素的表進(jìn)行排序總共進(jìn)行至多n-1次交換。在所有的完全依靠交換去移動(dòng)元素的排序方法中,選擇排序?qū)儆诜浅:玫囊环N。

插入排序

"""

1. 插入排序:同樣是把列表分為兩部分,前面一部分有序,后面一部分無序,每次從后面選擇第一個(gè)元素插入到前面有序序列中

2. 對(duì)一個(gè)變量進(jìn)行加減操作的判斷一般使用while循環(huán)

3. 優(yōu)化:因?yàn)榍耙徊糠忠呀?jīng)是從小到大排列的了, 所以如果從后面選出的最小元素大于前面的元素,那么就一定比前面的前面還要大,這時(shí)候就不需要進(jìn)行比較了

4. 最優(yōu)算法復(fù)雜度:假設(shè)列表已經(jīng)是從小到大排序好, 那么while循環(huán)進(jìn)入一次就退出,總共進(jìn)入n-1次,所以算法復(fù)雜度是O(n)

5. 最壞算法復(fù)雜度:假設(shè)列表是完全無序,或者說是從大到小排列的,那么內(nèi)層循環(huán)是n-1 n-2 n-3 ...,和n是有關(guān)的,所以復(fù)雜度是O(n2)

6. 穩(wěn)定性:因?yàn)楸容^是這樣進(jìn)行的:拿無序的第一個(gè)元素和前面的比較,比如說前面最大66,后面有一個(gè)66,因?yàn)楹竺娴?6不比前面的66大,所以位置不改變,

所以插入排序是穩(wěn)定的

"""

def insert_sort(alist):

"""

選擇排序

:param alist:

:return:

"""

n = len(alist)

for j in range(1, n):

i = j

while i > 0:

if alist[i] < alist[i-1]:

alist[i], alist[i-1] = alist[i-1], alist[i]

i -= 1

else:

break

插入排序(英語:Insertion Sort)是一種簡單直觀的排序算法。它的工作原理是通過構(gòu)建有序序列,對(duì)于未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應(yīng)位置并插入。插入排序在實(shí)現(xiàn)上,在從后向前掃描過程中,需要反復(fù)把已排序元素逐步向后挪位,為最新元素提供插入空間。

希爾排序

"""

希爾排序是通過步長把原來的序列分為好幾部分,每一個(gè)部分采用插入排序,然后調(diào)整步長,重復(fù)這個(gè)過程

最壞時(shí)間復(fù)雜度考慮gap取1,這就是完全的插入排除

"""

def shell_sort(alist):

n = len(alist)

gap = n // 2

# gap 必須能取到1

while gap > 0:

# 插入算法,與普通的插入算法的區(qū)別就是gap步長

for j in range(gap, n):

i = j

while i > 0:

if alist[i] < alist[i-gap]:

alist[i], alist[i-gap] = alist[i-gap], alist[i]

i -= gap

else:

break

gap //= 2

快速排序

快速排序(英語:Quicksort),又稱劃分交換排序(partition-exchange sort),通過一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小,然后再按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,整個(gè)排序過程可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列。

步驟為:

從數(shù)列中挑出一個(gè)元素,稱為"基準(zhǔn)"(pivot),

重新排序數(shù)列,所有元素比基準(zhǔn)值小的擺放在基準(zhǔn)前面,所有元素比基準(zhǔn)值大的擺在基準(zhǔn)的后面(相同的數(shù)可以到任一邊)。在這個(gè)分區(qū)結(jié)束之后,該基準(zhǔn)就處于數(shù)列的中間位置。這個(gè)稱為分區(qū)(partition)操作。

遞歸地(recursive)把小于基準(zhǔn)值元素的子數(shù)列和大于基準(zhǔn)值元素的子數(shù)列排序。

遞歸的最底部情形,是數(shù)列的大小是零或一,也就是永遠(yuǎn)都已經(jīng)被排序好了。雖然一直遞歸下去,但是這個(gè)算法總會(huì)結(jié)束,因?yàn)樵诿看蔚牡?#xff08;iteration)中,它至少會(huì)把一個(gè)元素?cái)[到它最后的位置去。

"""

1. 快速排序是一種常用的排序算法,本質(zhì)是找到每一個(gè)元素在原列表的真實(shí)位置

2. 因?yàn)樾枰判虻氖窃斜?#xff0c;如果quick_sort(alist[0:low]) 這種方式排序的是新列表,和原列表脫離了關(guān)系,所以采用多傳參數(shù)的方式,傳的參數(shù)是列表位置

3. 最壞時(shí)間復(fù)雜度:考慮最壞的情況,每次找到的元素位置就是在最左邊,那時(shí)間復(fù)雜度是O(n2)

4. 最優(yōu)時(shí)間復(fù)雜度:考慮最好的情況,每次找到的元素在最中間,每次low和high移動(dòng)之和是n,總共移動(dòng)多少次?

每次都是對(duì)半分割 2*2*.. = N 個(gè)數(shù)字,次數(shù)是logn,所以O(shè)(nlogn)

"""

def quick_sort(alist, start, end):

"""

快速排序

:param alist:

:return:

"""

# n = len(alist)

if start >= end:

return

mid = alist[start]

low = start

high = end

while low < high:

# 這里用alist[high] >= mid 而不是alist[high]>mid是為了把所有和中間值相等的都移動(dòng)到一遍,而不是移來移去

while low < high and alist[high] >= mid:

high -= 1

alist[low] = alist[high]

while low < high and alist[low] < mid:

low += 1

alist[high] = alist[low]

# while low < high:

# while low < high:

# if alist[high] < mid:

# alist[low] = alist[high]

# # 這時(shí)候應(yīng)該移動(dòng)low了

# break

# # 這個(gè)else就是循環(huán)移動(dòng)

# else:

# high -= 1

# while low < high:

# if alist[low] > mid:

# alist[high] = alist[low]

# # 這時(shí)候應(yīng)該移動(dòng)high了

# break

# else:

# low += 1

alist[low] = mid

quick_sort(alist, start, low)

quick_sort(alist, low+1, end)

歸并排序

歸并排序是采用分治法的一個(gè)非常典型的應(yīng)用。歸并排序的思想就是先遞歸分解數(shù)組,再合并數(shù)組。

將數(shù)組分解最小之后,然后合并兩個(gè)有序數(shù)組,基本思路是比較兩個(gè)數(shù)組的最前面的數(shù),誰小就先取誰,取了后相應(yīng)的指針就往后移一位。然后再比較,直至一個(gè)數(shù)組為空,最后把另一個(gè)數(shù)組的剩余部分復(fù)制過來即可。

"""

1. 歸并排序采用遞歸,可以用這個(gè)排序算法好好體會(huì)一下遞歸的流程思想.其中遞歸編程思想和執(zhí)行思想是有區(qū)別的,編程思想是不考慮底下的層,只著眼于

當(dāng)前層,最后考慮細(xì)枝末節(jié)。執(zhí)行思想是嵌套

2. 最優(yōu)時(shí)間復(fù)雜度和最壞時(shí)間復(fù)雜度是一樣的:每一層的歸并用來兩個(gè)指針,相加的和是 n ,每次對(duì)半分,總共分了logn次(和快速排序一樣),時(shí)間復(fù)雜度是O(nlogn)

"""

def merge_sort(alist):

n = len(alist)

if n <= 1:

return alist

# 分為兩部分,對(duì)每部分進(jìn)行排序

mid = n // 2

# 假設(shè)這已經(jīng)是排序好的了

left = merge_sort(alist[0:mid])

right = merge_sort(alist[mid:])

# 對(duì)排序好的進(jìn)行合并

left_index = 0

right_index = 0

result = []

while left_index < len(left) and right_index < len(right):

if left[left_index] < right[right_index]:

result.append(left[left_index])

left_index += 1

else:

result.append(right[right_index])

right_index += 1

# 如果左邊先走到盡頭,則把右邊剩余所有加進(jìn)來;如果右邊先走到盡頭,則把左邊剩余所有加進(jìn)來

# 最終第一層的result把left 和 right 的result 都包含進(jìn)來了

result += left[left_index:]

result += right[right_index:]

return result

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的python实现排序算法_python实现各种排序算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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