Python實現十大基礎算法


十大基本排序算法

排序算法是《數據結構與算法》中最基本的算法之一。

排序算法可以分為內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。常見的內部排序算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸並排序、快速排序、堆排序、基數排序等。這里使用python實現這十大排序算法。

 

 

 

 

一、冒泡排序

算法步驟

       比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

  對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對。這步做完后,最后的元素會是最大的數。

  針對所有的元素重復以上的步驟,除了最后一個。

  持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。

# 冒泡排序
def bubbleSort(arr):
    for i in range(1, len(arr)):
        for j in range(0, len(arr)-i):
            if arr[j] > arr[j+1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

 

二、選擇排序

算法步驟

  首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

  再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。

  重復第二步,直到所有元素均排序完畢。

#選擇排序
def selectionSort(arr):
    for i in range(len(arr) - 1):
        # 記錄最小數的索引
        minIndex = i
        for j in range(i + 1, len(arr)):
            if arr[j] < arr[minIndex]:
                minIndex = j
        # i 不是最小數時,將 i 和最小數進行交換
        if i != minIndex:
            arr[i], arr[minIndex] = arr[minIndex], arr[i]
    return arr

 

三、插入排序

算法步驟

       將第一待排序序列第一個元素看做一個有序序列,把第二個元素到最后一個元素當成是未排序序列。

  從頭到尾依次掃描未排序序列,將掃描到的每個元素插入有序序列的適當位置。(如果待插入的元素與有序序列中的某個元素相等,則將待插入元素插入到相等元素的后面。)

 

# 插入排序
def insertionSort(arr):
    for i in range(len(arr)):
        preIndex = i-1
        current = arr[i]
        while preIndex >= 0 and arr[preIndex] > current:
            arr[preIndex+1] = arr[preIndex]
            preIndex-=1
        arr[preIndex+1] = current
    return arr

 

四、希爾排序

算法步驟

       選擇一個增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;

  按增量序列個數 k,對序列進行 k 趟排序;

  每趟排序,根據對應的增量 ti,將待排序列分割成若干長度為 m 的子序列,分別對各子表進行直接插入排序。僅增量因子為 1 時,整個序列作為一個表來處理,表長度即為整個序列的長度。

# 希爾排序
def shellSort(arr):
    import math
    gap=1
    while(gap < len(arr)/3):
        gap = gap*3+1
    while gap > 0:
        for i in range(gap,len(arr)):
            temp = arr[i]
            j = i-gap
            while j >=0 and arr[j] > temp:
                arr[j+gap]=arr[j]
                j-=gap
            arr[j+gap] = temp
        gap = math.floor(gap/3)
    return arr

 

五、歸並排序

算法步驟

       1.申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合並后的序列;

  2.設定兩個指針,最初位置分別為兩個已經排序序列的起始位置;

  3.比較兩個指針所指向的元素,選擇相對小的元素放入到合並空間,並移動指針到下一位置;

  4.重復步驟 3 直到某一指針達到序列尾;

  5.將另一序列剩下的所有元素直接復制到合並序列尾。

#歸並排序
def mergeSort(arr):
    import math
    if(len(arr)<2):
        return arr
    middle = math.floor(len(arr)/2)
    left, right = arr[0:middle], arr[middle:]
    return merge(mergeSort(left), mergeSort(right))

def merge(left,right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0));
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0));
    return result

 

      

六、快速排序

算法步驟

       1.從數列中挑出一個元素,稱為 "基准"(pivot);

  2.重新排序數列,所有元素比基准值小的擺放在基准前面,所有元素比基准值大的擺在基准的后面(相同的數可以到任一邊)。在這個分區退出之后,該基准就處於數列的中間位置。這個稱為分區(partition)操作;

  3.遞歸地(recursive)把小於基准值元素的子數列和大於基准值元素的子數列排序。

#快速排序
def quickSort(arr, left=None, right=None):
    left = 0 if not isinstance(left,(int, float)) else left
    right = len(arr)-1 if not isinstance(right,(int, float)) else right
    if left < right:
        partitionIndex = partition(arr, left, right)
        quickSort(arr, left, partitionIndex-1)
        quickSort(arr, partitionIndex+1, right)
    return arr

def partition(arr, left, right):
    pivot = left
    index = pivot+1
    i = index
    while  i <= right:
        if arr[i] < arr[pivot]:
            swap(arr, i, index)
            index+=1
        i+=1
    swap(arr,pivot,index-1)
    return index-1

def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

 

七、堆排序

算法步驟

       1.創建一個堆 H[0……n-1];

  2.把堆首(最大值)和堆尾互換;

  3.把堆的尺寸縮小 1,並調用 shift_down(0),目的是把新的數組頂端數據調整到相應位置;

  4.重復步驟 2,直到堆的尺寸為 1。

#堆排序
def buildMaxHeap(arr):
    import math
    for i in range(math.floor(len(arr)/2),-1,-1):
        heapify(arr,i)

def heapify(arr, i):
    left = 2*i+1
    right = 2*i+2
    largest = i
    if left < arrLen and arr[left] > arr[largest]:
        largest = left
    if right < arrLen and arr[right] > arr[largest]:
        largest = right

    if largest != i:
        swap(arr, i, largest)
        heapify(arr, largest)

def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

def heapSort(arr):
    global arrLen
    arrLen = len(arr)
    buildMaxHeap(arr)
    for i in range(len(arr)-1,0,-1):
        swap(arr,0,i)
        arrLen -=1
        heapify(arr, 0)
    return arr

 

八、計數排序

算法步驟

  1.找出待排序的數組中最大和最小的元素

  2.統計數組中每個值為i的元素出現的次數,存入數組C的第i項

  3.對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加)

  4.反向填充目標數組:將每個元素i放在新數組的第C(i)項,每放一個元素就將C(i)減去1

#計數排序
def countingSort(arr, maxValue):
    bucketLen = maxValue+1
    bucket = [0]*bucketLen
    sortedIndex =0
    arrLen = len(arr)
    for i in range(arrLen):
        if not bucket[arr[i]]:
            bucket[arr[i]]=0
        bucket[arr[i]]+=1
    for j in range(bucketLen):
        while bucket[j]>0:
            arr[sortedIndex] = j
            sortedIndex+=1
            bucket[j]-=1
    return arr

 

九、桶排序

算法步驟

桶排序是計數排序的升級版。它利用了函數的映射關系,高效與否的關鍵就在於這個映射函數的確定。為了使桶排序更加高效,我們需要做到這兩點:

  1. 在額外空間充足的情況下,盡量增大桶的數量
  2. 使用的映射函數能夠將輸入的 N 個數據均勻的分配到 K 個桶中

同時,對於桶中元素的排序,選擇何種比較排序算法對於性能的影響至關重要。

def bucketSort(arr):
  # 選擇一個最大的數
  max_num = max(nums)
  # 創建一個元素全是0的列表, 當做桶
  bucket = [0]*(max_num+1)
  # 把所有元素放入桶中, 即把對應元素個數加一
  for i in nums:
    bucket[i] += 1
  # 存儲排序好的元素
  sort_arr = []
  # 取出桶中的元素
  for j in range(len(bucket)):
    if bucket[j] != 0:
      for y in range(bucket[j]):
        sort_nums.append(j)
  return sort_arr

 

十、基數排序

算法步驟

  先排元素的最后一位,再排倒數第二位,直到所有位數都排完

#基數排序
def radix_sort(s):
    i = 0 # 記錄當前正在排拿一位,最低位為1
    max_num = max(s)  # 最大值
    j = len(str(max_num))  # 記錄最大值的位數
    while i < j:
        bucket_list =[[] for _ in range(10)] #初始化桶數組
        for x in s:
            bucket_list[int(x / (10**i)) % 10].append(x) # 找到位置放入桶數組
        print(bucket_list)
        s.clear()
        for x in bucket_list:   # 放回原序列
            for y in x:
                s.append(y)
        i += 1

 

 在學習python實現基礎算法時,在GitHub上找到一個使用python實現算法可視化,作者是真的厲害,有興趣的可以去看下。

這里附上鏈接:https://github.com/ZQPei/Sorting_Visualization

 

 

                    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM