學習python中,順便溫習一下演算法,用python實現了一下冒泡、堆、快速 這3個排序演算法,並對時間複雜度進行了比較
用了random裡面的sample的,把有序的陣列變成隨機排列,為之後排序初始化資料
from random import sample
def initrandomdata(size):
#初始化規模為size的陣列
randomarray = [i for i in range(size)]
#從陣列中隨機取出資料
return sample(randomarray, size)
後面有用到簡單工廠(好吧,這存粹是為了好玩...),這邊定義了乙個排序的介面
class sort:
def sort(self):
return
定義了乙個繼承自sort的類,實現氣泡排序
class bubble(sort):
def __init__(self, randomarray):
#注意使用陣列拷貝,不然就引用傳遞了
self.randomarray = randomarray[:]
def sort(self):
randomarray = self.randomarray
for i in range(len(randomarray)):
for j in range(len(randomarray) - 1, i, -1):
if randomarray[j] > randomarray[j-1]:
temp = randomarray[j]
randomarray[j] = randomarray[j-1]
randomarray[j-1] = temp
from math import floor
class heap(sort):
def __init__(self, randomarray):
self.randomarray = randomarray[:]
def maxheapify(self, array, index, length):
max = index
leftchild = index * 2 + 1
rightchild = index * 2 + 2
#比較左右孩子和根節點的大小
if leftchild <= length and array[leftchild] > array[index]:
max = leftchild
if rightchild <= length and array[rightchild] > array[max]:
max = rightchild
if max != index:
temp = array[max]
array[max] = array[index]
array[index] = temp
#交換之後可能會造成之前調整的資料不符合堆的性質,遞迴來重新調整
self.maxheapify(array, max, length)
#建立大根堆
def buildmaxheapify(self):
#從最後乙個子節點的父節點開始遍歷,floor為math中的向下取整函式
start = floor((len(self.randomarray) - 2) / 2)
for i in range(start, -1, -1):
self.maxheapify(self.randomarray, i, len(self.randomarray) - 1)
def sort(self):
self.buildmaxheapify()
#完成堆初始化之後開始排序
for i in range(len(self.randomarray) - 1):
temp = self.randomarray[0]
self.randomarray[0] = self.randomarray[len(self.randomarray) - 1 - i]
self.randomarray[len(self.randomarray) - 1 - i] = temp
start = floor((len(self.randomarray) - i - 3) / 2)
self.maxheapify(self.randomarray, 0, len(self.randomarray) - 2 - i)
快速排序的演算法借用了維基百科上的,只有兩行的乙個演算法,看到之後才發現python原來還可以這麼用
class quick(sort):
def __init__(self, randomarray):
self.randomarray = randomarray
def quicksort(self, randomarray):
#當遞迴到子陣列只有乙個元素是,遞迴結束
if len(randomarray) == 0:
return
#遞迴,對陣列採用快速排序
return self.quicksort([i for i in randomarray[1:] if i < randomarray[0]]) + randomarray[0:1] + \
self.quicksort([i for i in randomarray[1:] if i >= randomarray[0]])
def sort(self):
self.quicksort(self.randomarray)
使用了下**,對排序進行了時間統計,還用了下簡單工廠,來建立各個實力,但是為什麼python寫出來總感覺怪怪的...
class proxy(sort):
obj = none
#通過建構函式建立
def __init__(self, name, randomarray):
if name == "bubble":
self.obj = bubble(randomarray)
if name == "heap":
self.obj = heap(randomarray)
if name == "quick":
self.obj = quick(randomarray)
#重寫了sort方法,加入排序時間的統計
def sort(self):
start = clock()
self.obj.sort()
print(clock() - start)
def main():
#輸入需要排序陣列的規模
size = int(input("input the size of list:"))
randomarray = initrandomdata(size)
#例項化3個排序的物件
很明顯的可以看出,氣泡排序的o(n
2) 的時間複雜妥妥的墊底。
堆排序o(nlog2n)的時間複雜度,在排序效率上明顯是要提高了很多。
快速排序,雖然存在o(n
2)的最壞情況(陣列為完全倒序排列),但是平均時間和最小時間上還是o(nlog2n)。
但是由於堆排序幾乎每次調換堆頂和堆底的元素之後都需要重新整理堆結構,所以他在常數上要比快速排序大得多,這就導致了堆排序雖然和快速排序時間複雜同為o(nlog2n),但是實際表現上堆排序還是不如快速排序的
Python快排與氣泡排序演算法(筆記)
def quicksort data 快速排序 if len data 2 遞迴入口及出口 mid data len data 2 選取基準值,也可以選取第乙個或最後乙個元素 left,right 定義基準值左右兩側的列表 data.remove mid 從原始陣列中移除基準值 for num in...
Python 實現快排 堆排
原理 公升序 選取陣列的首個元素做為中間值,快取這個中間值,該位置變為空 從右到左和中間值對比,找到第乙個小於中間值的元素,把該值放到左邊的空位,該位置變為空 從左到右和中間值對比,找到第乙個大於中間值的元素,把該值放到右邊的空位,該位置變為空 重複步驟2和3,直到左右空位相交,然後把快取的中間值填...
python實現快排 氣泡排序
1 快排 快排 從一堆雜亂的資料中挑選乙個基準值,將這些數字和基準值一一比較,大的放基準值的右邊,小的放左邊 實現思路 定義乙個函式,挑選列表的首個數字作為基準值,其他數字比基準值小的數字生成列表,同理,其他數字和基準值大的數字生成另乙個列表,再遞迴快排這兩個列表 def quick sort nu...