1. 程式人生 > >排序演算法Python實現合輯

排序演算法Python實現合輯

基本排序演算法:

1. 選擇排序(seletionSort):

搜尋整個列表,找到最小項的位置,如果該位置不是列表的第一個位置,演算法就交換這兩個位置的項。然後,演算法回到第二個位置,並重復這個過程。

時間複雜度為 O ( n 2 )

O(n^2)

《資料結構:Python語言描述》:

def swap(lyst, i, j):
    '''Exchanges the items at positions i and j'''
    temp = lyst[i]
    lyst[i] = lyst[j]
    lyst[j] =temp

def selectionSort(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, minIndex, i) i += 1 return Lyst

我自己根據書上改的:

def selectionSort(Lyst):
    i = 0
    while i < len(Lyst)
-1: j = i + 1 while j < len(Lyst): if Lyst[j] < Lyst[i]: Lyst[i],Lyst[j] = Lyst[j],Lyst[i] j += 1 i += 1 return Lyst

for 迴圈方法:

def selectionSort(list):
    length=len(list)
    for i in range(length):
        for j in range(i+1,length):
            if list[j] < list[i]:
                list[j],list[i]=list[i],list[j]
    return list
Lyst = [2,1,4,7,3,8,4,9,1,3]
print(selectionSort(Lyst))
[1, 1, 2, 3, 3, 4, 4, 7, 8, 9]

2. 氣泡排序(bubbleSort):

從列表的開頭處開始,比較一對資料項,知道移動到列表的末尾,這樣每趟排序會把最大的數字扔到最後面。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越大的元素會經由交換慢慢“浮”到數列的頂端,故名。

時間複雜度為 O ( n 2 ) O(n^2)

《資料結構:Python語言描述》:

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
    return lyst

for 迴圈方法:

def bubbleSort(lyst):
    # 外層迴圈控制從頭走到尾的次數
    for j in range(len(lyst) - 1):
        # 內層迴圈控制走一次的過程
        for i in range(0, len(lyst) - j - 1):
            # 如果前一個元素大於後一個元素,則交換兩個元素(升序)
            if lyst[i] > lyst[i + 1]:
                lyst[i], lyst[i + 1] = lyst[i + 1], lyst[i]
	return lyst

針對氣泡排序進行一個小的調整,將其最好情況下的效能提高到線性階,但平均複雜的仍是 O ( n 2 ) O(n^2)

def bubbleSortWithTweak(lyst):
    n = len(lyst)
    while n > 1:
        i = 1
        while i < n:
            if lyst[i] < lyst[i - 1]:
                swap(lyst, i , i-1)
                swapped = True
            i += 1
        if not swapped: return
        n -= 1
    return lyst

用遞迴實現冒泡?

3. 插入排序(insertionSort):

“一趟一個“地將待排序記錄插入到已經排好序的部分記錄的適當位置中,使其成為一個新的有序序列,直到所有待排序記錄全部插入完畢。在第i輪通過列表的時候(其中i的範圍從1到n-1),第i個項應該插入到列表的前i個項之中的正確位置。在第i輪之後,前i個項應該是排序好的。

列表中排好序的項越多,插入排序的效果越好。

時間複雜度為 O ( n 2 ) O(n^2)

《資料結構:Python語言描述》:

def insertSort(lyst):
    i = 1
    while i < len(lyst):
        itemToInsert = lyst[i]
        j = i - 1                
        while j >= 0:
            if itemToInsert < lyst[j]:
                lyst[j + 1] = lyst[j]
                j -= 1
            else:
                break
        lyst[j + 1] = itemToInsert
        i += 1
    return lyst

[2,4,3,1]>[2,4,3,1]>[2,3,4,1]>[2,3,1,4]>[2,1,3,4]>[1,2,3,4]

更快的排序演算法

採用分而治之(divide-and-conquer)的策略。將列表分解為更小的子列表,隨後,這些子列表遞迴的排序。演算法複雜度: O ( n l o g n ) O(nlogn)

1.1 快速排序(quickSort)

隨意選擇一個數字(可選中點)作為基準(pivot)分割列表,比基準數字大的放在右,比基準數字小的放在左。對於子列表,遞迴地重複應用該過程。直到子列表的長度最大為1。

《資料結構:Python語言描述》:

def swap(lyst, i, j):
    '''Exchanges the items at positions i and j'''
    temp = lyst[i]
    lyst[i] = lyst[j]
    lyst[j] =temp

def quickSort(lyst):
    quickSortHelper(lyst, 0, len(lyst)-1)

def quickSortHelper(lyst, left, right):
    if left < right:
        print(lyst)
        pivotLocation = partition(lyst, left, right)
        print(lyst[pivotLocation])
        quickSortHelper(lyst, left, pivotLocation - 1) 
        quickSortHelper(lyst, pivotLocation + 1, right)
            
def partition(lyst, left, right):
    middle = (left + right) // 2
    pivot = lyst[middle]
    lyst[middle] = lyst[right]
    lyst[right] = pivot
    boundary = left
    for index in range(left, right):
        if lyst[index] < pivot:
            swap(lyst, index, boundary)
            boundary += 1
            print(lyst)
    swap(lyst, right, boundary)
    return boundary

Lyst = [12,19,17,18,14,11,15,13,16]
quickSort(Lyst)
print(Lyst)

快速排序遞迴分析:

1.遍歷所有元素,使比基準小的在基準左,比基準大的在基準右,故先將基準換到最右側。

2.然後從左到右遍歷,找到比基準小的元素,從第一個位置開始依次互換。

3.如12先跟自己互換,然後11和19互換,然後13和17互換,最後基準14和18互換。

4.遞迴對左邊子列表重複操作:基準11換到末端即11和13互換,然後11和12互換。

5.左邊已不可再分,開始分右邊子列表。首先基準15換到末端即15和18互換,然後15

[12, 19, 17, 18, 14, 11, 15, 13, 16]
[12, 19, 17, 18, 16, 11, 15, 13, 14]
[12, 11, 17, 18, 16, 19, 15, 13, 14]
[12, 11, 13, 18, 16, 19, 15, 17, 14]
14
[12, 11, 13, 14, 16, 19, 15, 17, 18]
11
[11, 13, 12, 14, 16, 19, 15, 17, 18]
[11, 12, 13, 14, 16, 19, 15, 17, 18]
13
[11, 12, 13, 14, 16, 19, 15, 17, 18]
15
[11, 12, 13, 14, 15, 19, 18, 17, 16]
[11, 12, 13, 14, 15, 16, 19, 17, 18]
[11, 12, 13, 14, 15, 16, 17, 19, 18]
18
[11, 12, 13, 14, 15, 16, 17, 18, 19]
16
[11, 12, 13, 14, 15, 16, 17, 18, 19]

1.2 演算法導論 快速排序:

# quickSort, quickSortHelper 同上

def partition(lyst, left, right):
    x = lyst[right]
    i = left- 1
    for j in range(left, right):
        if lyst[j] <= x:
            i += 1
            lyst[i], lyst[j] = lyst[j], lyst[i]
            print(lyst)
    lyst[i + 1], lyst[right] = lyst[right], lyst[i+1]
    return i + 1

Lyst = [12,19,17,18,14,11,15,13,16]
quickSort(Lyst)
print(Lyst)
[12, 19, 17, 18, 14, 11, 15, 13, 16]
[12, 19, 17, 18, 14, 11, 15, 13, 16]
[12, 14, 17, 18, 19, 11, 15, 13, 16]
[12, 14, 11, 18, 19, 17, 15, 13, 16]
[12, 14, 11, 15, 19, 17, 18, 13, 16]
[12, 14, 11, 15, 13, 17, 18, 19, 16]
16
[12, 14, 11, 15, 13, 16, 18, 19, 17]
[12, 14, 11, 15, 13, 16, 18, 19, 17]
[12, 11, 14, 15, 13, 16, 18, 19, 17]
13
[12, 11, 13, 15, 14, 16, 18, 19, 17]
11
[11, 12, 13, 15, 14, 16, 18, 19, 17]
14
[11, 12, 13, 14, 15, 16, 18, 19, 17]
17
[11, 12, 13, 14, 15, 16, 17, 19, 18]
18
[11, 12, 13, 14, 15, 16, 17, 18, 19]

2.1 歸併排序(mergeSort)

建立在歸併操作上的一種有效的排序演算法,效率為 O ( n l o g n ) O(n log n) 。1945年由約翰·馮·諾伊曼首次提出。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用,且各層分治遞迴可以同時進行。

merge 函式將兩個排好序的子列表合併到一個大的排好序的子列表中,第1個子列表在low和middle之間,第2個子列表在middle+1到high之間。這個過程包含3個步驟:
1.將索引指標設定為每個子列表的第一項,分別是low和middle+1
2.從每個子列表的第一項開始,重複地比較各項。將較小的項從其子列表中複製到複製快取中,並且繼續處理子列表中的下一項。重複這個過程,直到兩個子列表中的所有的項都已經複製過了。如果先到達了其中的一個子列表的末尾,通過從另一個子列表複製剩餘的項,從而結束這個步驟。
3.將copyBuffer中的low和high之間的部分,複製回lyst中對應的位置。

《資料結構:Python語言描述》:

import sys
sys.path.append(r'C:\Users\Qiuyi\eclipse-workspace\DataStructure3.0\programs\Ch_4_Student_Files')

from arrays import Array

def mergeSort(lyst):
    copyBuffer = Array(len(lyst))
    mergeSortHelper(lyst, copyBuffer, 0, len(lyst)-1)
    
def mergeSortHelper(lyst, copyBuffer, low, high):
    if low < high:
        middle = (low + high) // 2
        mergeSortHelper(lyst, copyBuffer, low, middle)
        mergeSortHelper(lyst, copyBuffer, middle + 1, high)
        merge(lyst, copyBuffer, low, middle, high)
        
def merge(lyst, copyBuffer, low, middle, high):
    i1 = low
    i2 = middle + 1
    
    for i in range(low, high + 1):
        if i1 > middle:
            copyBuffer[i] = lyst[i2]
            i2 += 1
        elif i2 > high:
            copyBuffer[i] = lyst[i1]
            i1 += 1
        elif lyst[i1] < lyst[i2]:
            copyBuffer[i] = lyst[i1]
            i1 += 1
        else:
            copyBuffer[i] = lyst[i2]
            i2 += 1
    for i in range(low, high + 
            
           

相關推薦

排序演算法Python實現

基本排序演算法: 1. 選擇排序(seletionSort): 搜尋整個列表,找到最小項的位置,如果該位置不是列表的第一個位置,演算法就交換這兩個位置的項。然後,演算法回到第二個位置,並重復這個過程。 時間複雜度為

快速排序演算法Python實現

快速排序演算法,簡稱快排,是最實用的排序演算法,沒有之一,各大語言標準庫的排序函式也基本都是基於快排實現的。 本文用python語言介紹四種不同的快排實現。 1. 一行程式碼實現的簡潔版本 quick_sort = lambda array: array if le

排序,氣泡排序,快速排序演算法Python實現

桶排序 案例:學生分數為0~10,要按照從小到大排序: 1. 首先我們需要申請一個大小為10的陣列(python為列表),然後遍歷學生成績,每遍歷一個成績就在序號=成績的位置+1. 2. 生成完列

插入排序演算法python實現及分析

本文主要討論插入排序演算法解決n個數字自小到大的排序,及分析最壞情況和平均情況(複雜度)。       假設我們有一個n個數,要把它們按升序排序。按照我個人的思維最笨的辦法就是先掃描一遍(一個迭代),找出最小數,然後在剩餘的數字中,再找出最小的數字,按照這種方法到排序下去,最

【S-排序python實現八大排序演算法之4-希爾排序ShellSort

希爾排序ShellSort 起源: 直接插入法的改進演算法。希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序演算法的一種更高效的改進版本。希爾排序是非穩定排序演算

python對常見排序演算法實現

import random def random_nums_generator(max_value=1000, total_nums=20): """ 隨機數列表生成器 一些常用函式: random隨機數生成 random.random()用於生成一個0到

十大排序演算法及其實現(C++ & Python

經典的幾大排序演算法,網上各種版本程式碼質量層次不齊。在此想自己做個總結,一方面希望通過這次總結加深自己對幾種排序演算法的認識和記憶,另一方面也希望能寫下來與大家分享。 每個演算法力求給出普通解法和最優解法,當前部分排序演算法還沒有給出最優解,待後續的

【S-排序python實現八大排序演算法之9-桶排序(BucketSort)

桶排序 基本思想: 基本思想很簡單,如果有一個數組A,包含N個整數,值從1到M,桶排序(BucketSort)。留置一個數組S,裡面含有M個桶,初始化為0。然後遍歷陣列A,讀入Ai時,S[Ai]增一

演算法學習(1):排序演算法-插入排序python實現

前言 插入排序應該是最容易想到的排序演算法,其核心思想是:將待排序的序列看成兩部分,以某一個元素為界,左邊的是排好序的序列,右邊是待排序的序列,每次讀取邊界上的一個元素,然後將它跟排序好的序列中的元素一個一個對比,然後排好序的元素依次挪出個空位,然後將這個元素

python常見排序演算法實現(一)

在Python程式設計的實踐中,我們往往會遇到排序問題,比如在對搜尋引擎搜尋結果的排序(沒有排序就沒有Google、baidu等搜尋引擎的存在),當然,這樣的例子數不勝數。我大學中的必修課程《資料結構》

Python排序演算法實現

用Python實現了插入排序、希爾排序、氣泡排序、快速排序、直接選擇排序、堆排序、歸併排序、基數排序。 1、插入排序 描述 插入排序的基本操作就是將一個數據插入到已經排好序的有序資料中,從而得到一個新的、個數加一的有序資料,演算法適用於少量資

排序算法(四)堆排序Python實現及算法詳解

python 堆排序 一、前言如果需要Java版本的堆排序或者堆排序的基礎知識——樹的概念,請參看本人博文《排序算法(二)堆排序》關於選擇排序的問題選擇排序最大的問題,就是不能知道待排序數據是否已經有序,比較了所有數據也沒有在比較中確定數據的順序。堆排序對簡單選擇排序進行了改進。二、準備知識堆:它是一

【程序員筆試面試必會——排序②】Python實現 計數排序、基數排序

16px 最大 元素 size medium log n) python實現 count 一、計數排序 概要:     時間復雜度O(n),空間復雜度O(k),k是輸入序列的值的範圍(最大值-最小值),是穩定的。計數排序一般用於已知輸入值的範圍相對較小,比如給公司員工的身高

冒泡選擇插入希爾歸並快速排序python實現

python實現 election count partition sub star poi point shell def bubble_sort(a_list): for pass_num in range(len(a_list) - 1, 0, -1):

選擇排序python實現

bsp index dsm col 選擇排序 pytho 一個數 pan lin def findsmallestindex(arr): smallnum = arr[0] smallindex = 0 # 尋找最小元素的位置 for i

排序Python實現

int 時間復雜度 pri 開始 堆排序 空間復雜度 繼續 末尾 小頂堆 堆排序(Heap Sort) 堆是一棵具有以下性質的完全二叉樹: 大頂堆:每個結點的值都大於或等於其左右孩子結點的值 小頂堆:每個結點的值都小於或等於其左右孩子結點的值 堆排序的主要思想: 將

Java快速排序演算法實現

高快省的排序演算法 有沒有既不浪費空間又可以快一點的排序演算法呢?那就是“快速排序”啦!光聽這個名字是不是就覺得很高階呢。 假設我們現在對“6  1  2  7  9  3  4  5 10  8”這

基本排序演算法-java實現

最近重新學習了排序演算法,之前每次看完當時理解了,但是過一段時間就又忘了,尤其是程式碼,如果放一段時間有很多base case不知道怎麼寫了,所以還是應該詳細的解讀一下再不斷了敲程式碼才能理解比較深刻。 1.氣泡排序(bubble sort) 氣泡排序是一種簡單的排序演算法。其基本思

機器學習實戰——k-近鄰演算法Python實現問題記錄

  準備 kNN.py 的python模組 from numpy import * import operator def createDataSet(): group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])

十大排序演算法實現 十大經典排序演算法最強總結(含JAVA程式碼實現

十大經典排序演算法最強總結(含JAVA程式碼實現)   最近幾天在研究排序演算法,看了很多部落格,發現網上有的文章中對排序演算法解釋的並不是很透徹,而且有很多程式碼都是錯誤的,例如有的文章中在“桶排序”演算法中對每個桶進行排序直接使用了Collection.sort