演算法之排序 快速排序

2021-10-07 20:50:34 字數 2494 閱讀 9597

快排(快速排序)也是遞迴排序中的一種,也是分而治之的思想在排序中的乙個體現,另乙個體現為歸併排序;

相對於歸併排序,快排沒有使用其他陣列,沒有額外的空間複雜度;

快排的思想也是分組,不同於歸併排序,歸併排序用額外的陣列來合併分組;而快排,不實用額外陣列。

歸併排序:遞迴分組,當分組到最小值(陣列length<=1)時,再用乙個新陣列,遞迴合併分組。

快速排序:遞迴分組,選擇基點(任意選擇),根據基點做排序後,利用基點進行分組;依次遞迴。

快速排序的3個基本步驟:從陣列中選擇乙個元素作為基準點

分割槽,排序陣列,所有比基準值小的元素擺放在左邊區域,而大於基準值的擺放在右邊區域。每次分割結束以後基準值會插入到中間去。

最後利用遞迴,將擺放在左邊的陣列和右邊的陣列在進行一次上述的1和2操作。

分割槽會用到兩個指標,乙個指標會指向比基點大的元素,乙個指標指向比基點小的元素;

兩個指標可以在同乙個方向,也可以在不同方向;

通用部分**:

// 交換陣列元素

function

switchitem

(arr, a, b)

// 快速排序

function

quicksort

(arr)

// 分組後遞迴排序

function

quick

(arr, left, right)

if(indext +

1< right)

}return arr

}

針對分割槽時;指標放置方向不同,分割槽方式也不同,介紹兩種分割槽方式:

方式一:指標在不同方向

步驟如下:

左指標逐個格仔向右移動,當遇到大於或等於基點的值時,就停下來。

右指標逐個格仔向左移動,當遇到小於或等於基點的值時,就停下來。

將兩指標所指的值交換位置。

重複上述步驟,直至兩指標重合,或左指標移到右指標的右邊。

將基點與左指標所指的值交換位置。

示意圖如下(選取最左邊元素為基點):

**如下:

function

partition

(arr, left, right)

// 右指標移動

while

(left < right && arr[point]

<= arr[right]

)// 當左右指標停下,滿足條件,交換元素

if(left < right)

}// 交換基點和左指標

switchitem

(arr, left, point)

// 返回基點所在指標,為了後面遞迴分割槽

return left

}

方式二:指標在同方向步驟如下(以指標方向同在左邊為例):

兩個指標分別為上下指標,初始化都指向形參為left的元素。

上指標依次遍歷陣列;當遇見小於基點的元素停下;

交換上指標和下指標元素;下指標元素加1;

迴圈完後,交換基點和下指標元素。

下指標指向第乙個大於基點的元素;上指標總在尋找小於基點的元素。

當上下指標交換後,下指標後面的元素均小於基點;

最後迴圈完畢後,下指標和基點交換後,分割槽完成。小於基點的元素在下指標左邊,大於基點的元素在下指標右邊。

且基點已經放置到分割槽中間。

function

partition

(arr, left, right)

}switchitem

(arr, point, dpoint)

return dpoint

}

排序演算法之快速排序

快速排序使用分治法 divide and conquer 策略來把乙個序列 list 分為兩個子串行 sub lists 步驟為 從數列中挑出乙個元素,稱為 基準 pivot 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面 相同的數可以到任一邊 在這個分割槽退出...

排序演算法之快速排序

快速排序入口 public void quicksort int lists 遞迴呼叫該函式。原理 每次從陣列從選乙個標兵 本實現為簡單起見直接選取給定範圍內的第乙個元素為標兵 讓後在給定範圍內進行雙向遍歷,目的是以標兵為分界線,將所有小於標兵值的數字排一邊,將所有大於標兵的數字 放到另一邊。標兵移...

排序演算法之快速排序

快速排序是一種不穩定的排序演算法,它的基本思想是,以某個元素為基準,將所有大於等於它的值放在右邊,小於它的值放在左邊,這樣陣列就被分為兩部分,遞迴對這兩部分進行快速排序,而單個元素我們認為是已經排好序的。這是一種歸併思想,當然在最後一步,合併,我們什麼也沒有做也不用做。每一次排序都有乙個元素被放在正...