快排(快速排序)也是遞迴排序中的一種,也是分而治之的思想在排序中的乙個體現,另乙個體現為歸併排序;
相對於歸併排序,快排沒有使用其他陣列,沒有額外的空間複雜度;
快排的思想也是分組,不同於歸併排序,歸併排序用額外的陣列來合併分組;而快排,不實用額外陣列。
歸併排序:遞迴分組,當分組到最小值(陣列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 遞迴呼叫該函式。原理 每次從陣列從選乙個標兵 本實現為簡單起見直接選取給定範圍內的第乙個元素為標兵 讓後在給定範圍內進行雙向遍歷,目的是以標兵為分界線,將所有小於標兵值的數字排一邊,將所有大於標兵的數字 放到另一邊。標兵移...
排序演算法之快速排序
快速排序是一種不穩定的排序演算法,它的基本思想是,以某個元素為基準,將所有大於等於它的值放在右邊,小於它的值放在左邊,這樣陣列就被分為兩部分,遞迴對這兩部分進行快速排序,而單個元素我們認為是已經排好序的。這是一種歸併思想,當然在最後一步,合併,我們什麼也沒有做也不用做。每一次排序都有乙個元素被放在正...