1. 程式人生 > >排序(四) 快速排序

排序(四) 快速排序

原始快速排序:選取最左邊元素作為標準,將所有小於它的元素放在左邊,大於它的元素放在右邊

# quick_sort.py

# [l,r]
def swap(a,b):
    return b,a

def __partition(array,l,r):
    e = array[l]
    j = l
    for i in range(l+1,r+1):
        if(array[i]<e):
            array[i], array[j + 1] = swap(array[i],array[j+1])
            j+=1
        i+=1
    array[l], array[j] = swap(array[l],array[j])
    return j

def __quickSort(array,l,r):
    if(l>=r):
        return;
    p = __partition(array,l,r)
    __quickSort(array,l,p-1)
    __quickSort(array,p+1,r)

def quickSort(array,n):
    __quickSort(array,0,n-1)

當數列幾乎為有序數列時,導致樹不平衡,退化為O(n²) 

隨機快速排序:選取隨機元素,選其作為標準,與最左邊元素交換。將所有小於它的元素放在左邊,大於它的元素放在右邊

# quick_sort_random.py

import random
# [l,r]
def swap(a,b):
    return b,a

def __partition(array,l,r):
    array[l], array[random.randint(l, r)] = swap(array[l],array[random.randint(l,r)])

    e = array[l]
    j = l
    for i in range(l+1,r+1):
        if(array[i]<e):
            array[i], array[j + 1] = swap(array[i],array[j+1])
            j+=1
        i+=1
    array[l], array[j] = swap(array[l],array[j])
    return j

def __quickSort(array,l,r):
    if(l>=r):
        return;
    p = __partition(array,l,r)
    __quickSort(array,l,p-1)
    __quickSort(array,p+1,r)

def quickSort(array,n):
    __quickSort(array,0,n-1)

 重複鍵值過多時,樹不平衡,退化為O(n²)

雙路快速排序:首尾兩指標,小於標準左放,大於標準右放

# quick_sort2.py

import random
# [l,r]

def swap(a,b):
    return b,a

def __partition2(array,l,r):
    array[l], array[random.randint(l, r)] = swap(array[l],array[random.randint(l,r)])

    e = array[l]
    i = l+1
    j = r
    while(1):
        while((i<=r) and (array[i]<e)):
            i+=1
        while((j>=l+1) and (array[j]>e)):
            j-=1
        if(i>j):
            break
        array[i],array[j] = swap(array[i],array[j])
        i+=1
        j-=1
    array[l],array[j] = swap(array[l],array[j])
    return j


def __quickSort2(array,l,r):
    if(l>=r):
        return;
    p = __partition2(array,l,r)
    __quickSort2(array,l,p-1)
    __quickSort2(array,p+1,r)

def quickSort2(array,n):
    __quickSort2(array,0,n-1)

三路快速排序:三指標,gt == i時,最左元素與最後一個小於它的元素(lt指向)交換

# quick_sort3ways.py

import random

def swap(a,b):
    return b,a

def __partition(array,l,r):
    array[l],array[random.randint(l,r)] = swap(array[l],array[random.randint(l,r)])

    e = array[l]
    i = l+1 # array[lt+1...i)==e
    lt = l # array[l+1...lt]<e
    gt = r+1 # array[gt...r]>e
    while(i<gt):
        if(array[i]<e):
            array[lt+1],array[i] = swap(array[lt+1],array[i])
            i+=1
            lt+=1
        elif(array[i]==e):
            i+=1
        else:
            array[gt-1],array[i] = swap(array[gt-1],array[i])
            gt-=1
    array[l],array[lt] = swap(array[l],array[lt])
    return lt,gt

def __quickSort3Ways(array,l,r):
    if(l>=r):
        return;
    p1,p2 = __partition(array,l,r)
    __quickSort3Ways(array,l,p1-1)
    __quickSort3Ways(array,p2,r)

def quickSort3Ways(array,n):
    __quickSort3Ways(array,0,n-1)

重複鍵值很多時,三路快速排序效果顯著

相關推薦

排序 快速排序

原始快速排序:選取最左邊元素作為標準,將所有小於它的元素放在左邊,大於它的元素放在右邊 # quick_sort.py # [l,r] def swap(a,b): return b,a def __partition(array,l,r): e = a

【算法】排序快速排序

情況 java while random chang 歸並 快速排序 並排 pub 正文之前 快速排序(英語:Quicksort),又稱劃分交換排序(partition-exchange sort),一種排序算法,最早由東尼 * 霍爾提出。在平均狀況下,排序n個項目要O(

java算法----排序----4快速排序

sort pre alt () ram pack image ret println 1 package log; 2 3 public class Test4 { 4 5 /** 6 * java算法---快速排序 7 *

內部排序快速排序

快速排序(QuickSort)是對氣泡排序的一種改進,故在介紹快速排序之前,我們先介紹氣泡排序。 1、氣泡排序 原理:將第一個記錄的關鍵字和第二個記錄的關鍵字進行比較,若為逆序,則交換(假設正序

排序快速排序

快速排序法 快速排序法相交之前的三種排序法來講,是一種執行速度較快的排序演算法,也是一種大家經常使用的排序演算法。 快速排序法使用一種分治的思想,將待排陣列切分成兩個子陣列,將兩個子陣列進行獨自的排序。 與歸併排序的區別 快速排序法與歸併排序不同,歸併排序是將兩個有序的

排序算法排序的Python實現及算法詳解

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

【算法】排序歸並排序

logs sta images pri 第一步 dom -o body 升序 上次給大家說了說簡單的冒泡排序,這次我們來說一說插入排序 插入排序的做法就像是我們日常生活中玩撲克牌一樣,每次抽一張牌,將撲克牌按一定順序插入手牌中,一步步完成排序 本文將介紹以下內容 排序思

排序算法排序

htc 有序 結構 info 最後一個元素 www 當前 最好 下標 1,什麽是堆 堆是具有下列性質的完全二叉樹: 每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆 (例如圖 9-2 左圖所示) ; 或者每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆(例如圖

小橙書閱讀指南——快速排序和三向切分快速排序

指針 rri 位置 容易 情況 相關鏈接 created style 了解 算法描述:快速排序是一種分治的排序算法。它將數組分為兩個子數組,並將兩部分獨立的排列。快速排序和歸並排序是互補的:歸並排序將數組分成兩個子數組分別排序,並將子數組歸並以將整個數組排序;而快速排序將數

八大排序算法總結:快速排序

con 遞歸調用 結果 width 算法總結 調用 小數 排序算法總結 png 目的:掌握 快速排序 的 基本思想與過程、代碼實現、時間復雜度 1、基本思想與過程:(分治思想,挖坑填數)   (1)從數列中選擇一個數作為key值;   (2)將比這個數小的數全部放在它的左邊

JAVA基礎28---快速排序

快速排序 實現快速排序演算法的關鍵在於陣列中選擇一個數字,接下來把陣列中的 數字分為兩部分,比選擇數字小的數字移動到陣列的左邊,比選擇數字大的數字移動到陣列的右邊。 具體實現演算法為: 設要排序的陣列是A【0】......A【N-1】,首先任意選取一個數據(通常選用第一個元素)作為基

從零開始學演算法歸併排序

從零開始學演算法(四)歸併排序 歸併排序 演算法介紹 演算法原理 演算法簡單記憶說明 演算法複雜度和穩定性 程式碼實現 歸併排序 程式碼是Javascript語言寫的(幾乎是虛擬碼) 演算

八大排序演算法——快速排序

快速排序可能是應用最廣泛的排序演算法。快速排序流行的原因是因為它實現簡單、適用於各種不同的輸入資料且在一般應用中比其他排序演算法都要快的多。快速排序的特點包括它是原地排序(只需要一個很小的輔助棧),且將長度為n的陣列排序所需的時間和nlogn成正比。快速排序的內迴圈比大多數排序演算法都要短小,這

排序演算法5--快速排序QuickSort

快速排序 時間複雜度: 平均O(nlogn) 最差的情況就是每一次取到的元素就是陣列中最小/最大的,這種情況其實就是氣泡排序了(每一次都排好一個元素的順序) 這種情況時間複雜度,就是氣泡排序的時間複雜度:T[n] = n * (n-1) = n^2 + n; 綜

java排序演算法------歸併排序

歸併排序: 是利用歸併的思想實現的排序方法,該演算法採用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然後遞迴求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。 合

再談資料結構排序與查詢

1 - 引言 雖然C++中的STL庫中提供了許多排序和查詢的方法。但是我們還是需要了解一下排序和查詢內部的原理,下面讓我們學習一下各類排序與查詢演算法 2 - 歸併排序 第一種高效的排序演算法是歸併排序,按照分治三步法,對歸併排序演算法介紹如下: 劃分問題:把序列分成

Java記憶體模型FAQ排序意味著什麼?

譯者:Alex 在很多情況下,訪問一個程式變數(物件例項欄位,類靜態欄位和陣列元素)可能會使用不同的順序執行,而不是程式語義所指定的順序執行。編譯器能夠自由的以優化的名義去改變指令順序。在特定的環境下,處理器可能會次序顛倒的執行指令。資料可能在暫存器,處理器緩衝區和主記憶體中以不同的次序移動

java 實現 常見排序演算法快速排序

大家好,我是烤鴨:        今天分享一下基礎排序演算法之快速排序。快速排序是內部排序(基於比較排序)中最好的比較演算法。   1.     快速排序:

演算法介紹2 快速排序演算法

                  本篇介紹快速排序演算法,以及相應的時間空間複雜度求解。               &nb

分治法在排序演算法中的應用JAVA--快速排序Lomuto劃分、Hoare劃分、隨機化快排

分治法在排序演算法中的應用 快速排序:時間複雜度O(nlogn) 如果說歸併排序是按照元素在陣列中的位置劃分的話,那麼快速排序就是按照元素的值進行劃分。劃分方法由兩種,本節將主要介紹Huare劃分,在減治法在查詢演算法中的應用(JAVA)--快速查詢這篇文章中講述了Lomu