當前位置:首頁 » 操作系統 » 排序演算法快速排序

排序演算法快速排序

發布時間: 2022-05-16 06:26:01

① 排序的快速排序

快速排序是目前已知的常用排序演算法中最快的排序方法。 優點:極快,數據移動少;
缺點:不穩定。 program kuaipai;
var
a:array[1..100]of integer;
k,l,n,i:integer;
procere kp(z,y:integer);
var
i,j,t:integer;
begin
i:=z;
j:=y;
t:=a[i];
repeat
while (a[j]>t)and(j>i) do
begin
inc(k);
dec(j);
end;
if i<j then
begin
a[i]:=a[j];
inc(i);
inc(l);
while (a[i]<t)and(i<j) do
begin
inc(k);
inc(i);
end;
if i<j then begin
a[j]:=a[i];
dec(j);
inc(l);
end;
end;
until i=j;
a[i]:=t;
inc(i);
dec(j);
inc(l);
if z<j then kp(z,j);
if i<y then kp(i,y);
end;
begin
readln(n);
for i:=1 to n do
read(a[i]);
k:=0;
l:=0;
kp(1,n);
for i:=1 to n do
write(a[i],' ');
end. //化分區間,找到最後元素的排序位置。並返回分隔的點(即最後一數據排序的位置)。
//劃分的區間是[nBegin, nEnd). pData是保存數據的指針
static int Partition(int[] pData, int nBeging, int nEnd)
{
int i = nBeging - 1; //分隔符號,最後nD保存在這里
--nEnd;
int nD = pData[nEnd]; //比較的數據。
int nTemp; // 交換用的臨時數據
//遍歷數據比較,找到nD的位置,這里注意,比較結果是,
//如果i的左邊是小於等於nD的,i的右邊是大於nD的
for (int j = nBeging; j < nEnd; ++j)
{
if (pData[j] <= nD) //如果數據比要比較的小,則在該數據的左邊,與i+1交換
{
++i; //小於nD的數據多一個,所以要加1,i的左邊數據都比nD小
nTemp = pData[i]; //交換數據
pData[i] = pData[j];
pData[j] = nTemp;
}
}
//最後不要忘了吧nD和i+1交換,因為這里就是nD的位置咯。
++i;
pData[nEnd] = pData[i];
pData[i] = nD;
return i; //返回nD的位置,就是分割的位置。
}
//排序的遞歸調用。
static int QuickSortRecursion(int[] pData, int nBeging, int nEnd)
{
if (nBeging >= nEnd -1) //如果區域不存在或只有一個數據則不遞歸排序
{
return 1;
}
//這里因為分割的時候,分割點處的數據就是排序中他的位置。
//也就是說他的左邊的數據都小於等於他,他右邊的數據都大於他。
//所以他不在遞歸調用的數據中。
int i = Partition(pData, nBeging, nEnd); //找到分割點
QuickSortRecursion(pData, nBeging, i); //遞歸左邊的排序
QuickSortRecursion(pData, i + 1, nEnd); //遞歸右邊的排序
return 1;
}
//快速排序
public static int QuickSort(int[] pData, int nLen)
{
//遞歸調用,快速排序。
QuickSortRecursion(pData, 0, nLen);
return 1;
}

② 快速排序特點

快速排序(Quicksort)是對冒泡排序的一種改進,由東尼·霍爾在1960年提出。 快速排序是指通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序。整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

分類
排序演算法

數據結構
不定

最壞空間復雜度
根據實現的方式不同而不同
快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分為兩個子序列(sub-lists)。

步驟為:

從數列中挑出一個元素,稱為「基準」(pivot),

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

遞歸地(recursively)把小於基準值元素的子數列和大於基準值元素的子數列排序。

遞歸到最底部時,數列的大小是零或一,也就是已經排序好了。這個演算法一定會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。

在簡單的偽代碼中,此演算法可以被表示為:

function quicksort(q)
{
var list less, pivotList, greater
if length(q) ≤ 1
return q
else
{
select a pivot value pivot from q
for each x in q except the pivot element
{
if x<pivot then add x to less
if x ≥ pivot then add x to greater
}
add pivot to pivotList
return concatenate(quicksort(less), pivotList, quicksort(greater))
}
}
原地(in-place)分區的版本

上面簡單版本的缺點是,它需要的額外存儲空間,也就跟歸並排序一樣不好。額外需要的存儲器空間配置,在實際上的實現,也會極度影響速度和緩存的性能。有一個比較復雜使用原地(in-place)分區演算法的版本,且在好的基準選擇上,平均可以達到空間的使用復雜度。

function partition(a, left, right, pivotIndex)
{
pivotValue = a[pivotIndex]
swap(a[pivotIndex], a[right]) // 把pivot移到結尾
storeIndex = left
for i from left to right-1
{
if a[i]<= pivotValue
{
swap(a[storeIndex], a[i])
storeIndex = storeIndex + 1
}
}
swap(a[right], a[storeIndex]) // 把pivot移到它最後的地方
return storeIndex
}
這是原地分區演算法,它分區了標示為"左邊(left)"和"右邊(right)"的序列部分,藉由移動小於的所有元素到子序列的開頭,留下所有大於或等於的元素接在他們後面。在這個過程它也為基準元素找尋最後擺放的位置,也就是它回傳的值。它暫時地把基準元素移到子序列的結尾,而不會被前述方式影響到。由於演算法只使用交換,因此最後的數列與原先的數列擁有一樣的元素。要注意的是,一個元素在到達它的最後位置前,可能會被交換很多次。

一旦我們有了這個分區演算法,要寫快速排列本身就很容易:

procere quicksort(a, left, right)
if right>left
select a pivot value a[pivotIndex]
pivotNewIndex := partition(a, left, right, pivotIndex)
quicksort(a, left, pivotNewIndex-1)
quicksort(a, pivotNewIndex+1, right)
這個版本經常會被使用在命令式語言中,像是C語言。

快速排序
快速排序是二叉查找樹(二叉搜索樹)的一個空間最優化版本。不是循序地把數據項插入到一個明確的樹中,而是由快速排序組織這些數據項到一個由遞歸調用所隱含的樹中。這兩個演算法完全地產生相同的比較次數,但是順序不同。對於排序演算法的穩定性指標,原地分區版本的快速排序演算法是不穩定的。其他變種是可以通過犧牲性能和空間來維護穩定性的。

③ 快速排序演算法原理與實現

快速排序的原理:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小。

然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

假設要排序的數組是A[1]……A[N],首先任意選取一個數據(通常選用第一個數據)作為關鍵數據,然後將所有比它的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一躺快速排序。一躺快速排序的演算法是:

1、設置兩個變數I、J,排序開始的時候I:=1,J:=N;

2、以第一個數組元素作為關鍵數據,賦值給X,即X:=A[1];

3、從J開始向前搜索,即由後開始向前搜索(J:=J-1),找到第一個小於X的值,兩者交換;

4、從I開始向後搜索,即由前開始向後搜索(I:=I+1),找到第一個大於X的值,兩者交換;

5、重復第3、4步,直到I=J。

(3)排序演算法快速排序擴展閱讀:

設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(通常選用數組的第一個數)作為關鍵數據,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。

值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。

一趟快速排序的演算法是:

1、設置兩個變數i、j,排序開始的時候:i=0,j=N-1;

2、以第一個數組元素作為關鍵數據,賦值給key,即key=A[0];

3、從j開始向前搜索,即由後開始向前搜索(j--),找到第一個小於key的值A[j],將A[j]的值賦給A[i];

4、從i開始向後搜索,即由前開始向後搜索(i++),找到第一個大於key的A[i],將A[i]的值賦給A[j];

5、重復第3、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小於key,4中A[i]不大於key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i, j指針位置不變。

④ 寫出快速排序的演算法

快速排序演算法通過多次比較和交換來實現排序,其排序演算法如下:
(1)首先設定一個分界值,通過該分界值將數組分成左右兩部分。
(2)將大於或等於分界值的數據集中到數組右邊,小於分界值的數據集中到數組的左邊。此時,左邊部分中各元素都小於或等於分界值,而右邊部分中各元素都大於或等於分界值。
(3)然後,左邊和右邊的數據可以獨立排序。對於左側的數組數據,又可以取一個分界值,將該部分數據分成左右兩部分,同樣在左邊放置較小值,右邊放置較大值。右側的數組數據也可以做類似處理。
(4)重復上述過程,可以看出,這是一個遞歸定義。通過遞歸將左側部分排好序後,再遞歸排好右側部分的順序。當左、右兩個部分各數據排序完成後,整個數組的排序也就完成了。

⑤ 快速排序是最好的排序演算法嗎

我們通常所說的排序演算法往往指的是內部排序演算法,即數據記錄在內存中進行排序。
排序演算法大體可分為兩種:
一種是比較排序,時間復雜度O(nlogn)
~
O(n^2),主要有:冒泡排序,選擇排序,插入排序,歸並排序,堆排序,快速排序等。
另一種是非比較排序,時間復雜度可以達到O(n),主要有:計數排序,基數排序,桶排序等。
我不知道你說的好是什麼標准,從時間上看,快速排序在比較排序中是最快的,但是快不過非比較排序。當然,在內存耗費上看,快速排序也不是耗費最小的。

⑥ 在各類演算法中那種演算法排序是最快的

說句實話,沒有最快這一說。

  1. 如果不在乎浪費空間,應該是桶排序最快

  2. 如果整體基本有序,插入排序最快

  3. 如果考慮綜合情況,快速排序更加實用常見(希爾排序、堆排序等各種排序也各有優劣)

  4. 一般情況下,冒泡這種排序僅僅是名字起的有趣罷了,不太好用

⑦ 排序演算法有哪些,簡述快速排序的核心

簡單的: 冒泡,選擇排序,插入排序,桶排序,

復雜點的: 堆排序,歸並排序,快速排序,

還有基數排序,計數排序(這兩個我還沒接觸到,不懂)

快速排序核心:

每次排序的時候設置一個基準點,將小於等於基準點的數全部放到基準點的左邊,將大於等於基準點的數全部放到基準點的右邊。這樣在每次交換的時候就不會像冒泡排序一樣只能在相鄰的數之間進行交換,交換的距離就大得多了。因此總的比較和交換次數就少了,速度自然就提高了。

圖片及快速排序簡述來源於<啊哈演算法>

⑧ C語言的快速排序的演算法是什麼啊

快速排序(Quicksort)是對冒泡排序的一種改進。由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。 演算法過程設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(通常選用第一個數據)作為關鍵數據,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。 一趟快速排序的演算法是: 1)設置兩個變數I、J,排序開始的時候:I=0,J=N-1; 2)以第一個數組元素作為關鍵數據,賦值給key,即 key=A[0]; 3)從J開始向前搜索,即由後開始向前搜索(J=J-1),找到第一個小於key的值A[J],並與key交換; 4)從I開始向後搜索,即由前開始向後搜索(I=I+1),找到第一個大於key的A[I],與key交換; 5)重復第3、4、5步,直到 I=J; (3,4步是在程序中沒找到時候j=j-1,i=i+1,直至找到為止。找到並交換的時候i, j指針位置不變。另外當i=j這過程一定正好是i+或j-完成的最後另循環結束。) 例如:待排序的數組A的值分別是:(初始關鍵數據:X=49) 注意關鍵X永遠不變,永遠是和X進行比較,無論在什麼位子,最後的目的就是把X放在中間,小的放前面大的放後面。 A[0] A[1] A[2] A[3] A[4] A[5] A[6]: 49 38 65 97 76 13 27 進行第一次交換後:27 38 65 97 76 13 49 ( 按照演算法的第三步從後面開始找) 進行第二次交換後:27 38 49 97 76 13 65 ( 按照演算法的第四步從前面開始找>X的值,65>49,兩者交換,此時:I=3 ) 進行第三次交換後:27 38 13 97 76 49 65 ( 按照演算法的第五步將又一次執行演算法的第三步從後開始找 進行第四次交換後:27 38 13 49 76 97 65 ( 按照演算法的第四步從前面開始找大於X的值,97>49,兩者交換,此時:I=4,J=6 ) 此時再執行第三步的時候就發現I=J,從而結束一趟快速排序,那麼經過一趟快速排序之後的結果是:27 38 13 49 76 97 65,即所有大於49的數全部在49的後面,所有小於49的數全部在49的前面。 快速排序就是遞歸調用此過程——在以49為中點分割這個數據序列,分別對前面一部分和後面一部分進行類似的快速排序,從而完成全部數據序列的快速排序,最後把此數據序列變成一個有序的序列,根據這種思想對於上述數組A的快速排序的全過程如圖6所示: 初始狀態 {49 38 65 97 76 13 27} 進行一次快速排序之後劃分為 {27 38 13} 49 {76 97 65} 分別對前後兩部分進行快速排序 {27 38 13} 經第三步和第四步交換後變成 {13 27 38} 完成排序。 {76 97 65} 經第三步和第四步交換後變成 {65 76 97} 完成排序。

⑨ 以下哪種排序演算法對進行的排序最快

1.選擇排序:不穩定,時間復雜度
O(n^2)
選擇排序的基本思想是對待排序的記錄序列進行n-1遍的處理,第i遍處理是將L[i..n]中最小者與L[i]交換位置。這樣,經過i遍處理之後,前i個記錄的位置已經是正確的了。
2.插入排序:穩定,時間復雜度
O(n^2)
插入排序的基本思想是,經過i-1遍處理後,L[1..i-1]己排好序。第i遍處理僅將L[i]插入L[1..i-1]的適當位置,使得L[1..i]
又是排好序的序列。要達到這個目的,我們可以用順序比較的方法。首先比較L[i]和L[i-1],如果L[i-1]≤
L[i],則L[1..i]已排好序,第i遍處理就結束了;否則交換L[i]與L[i-1]的位置,繼續比較L[i-1]和L[i-2],直到找到某一個位置j(1≤j≤i-1),使得L[j]
≤L[j+1]時為止。圖1演示了對4個元素進行插入排序的過程,共需要(a),(b),(c)三次插入。
3.冒泡排序:穩定,時間復雜度
O(n^2)
冒泡排序方法是最簡單的排序方法。這種方法的基本思想是,將待排序的元素看作是豎著排列的「氣泡」,較小的元素比較輕,從而要往上浮。在冒泡排序演算法中我們要對這個「氣泡」序列處理若干遍。所謂一遍處理,就是自底向上檢查一遍這個序列,並時刻注意兩個相鄰的元素的順序是否正確。如果發現兩個相鄰元素的順序不對,即「輕」的元素在下面,就交換它們的位置。顯然,處理一遍之後,「最輕」的元素就浮到了最高位置;處理二遍之後,「次輕」的元素就浮到了次高位置。在作第二遍處理時,由於最高位置上的元素已是「最輕」元素,所以不必檢查。一般地,第i遍處理時,不必檢查第i高位置以上的元素,因為經過前面i-1遍的處理,它們已正確地排好序。
4.堆排序:不穩定,時間復雜度
O(nlog
n)
堆排序是一種樹形選擇排序,在排序過程中,將A[n]看成是完全二叉樹的順序存儲結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關系來選擇最小的元素。
5.歸並排序:穩定,時間復雜度
O(nlog
n)
設有兩個有序(升序)序列存儲在同一數組中相鄰的位置上,不妨設為A[l..m],A[m+1..h],將它們歸並為一個有序數列,並存儲在A[l..h]。
6.快速排序:不穩定,時間復雜度
最理想
O(nlogn)
最差時間O(n^2)
快速排序是對冒泡排序的一種本質改進。它的基本思想是通過一趟掃描後,使得排序序列的長度能大幅度地減少。在冒泡排序中,一次掃描只能確保最大數值的數移到正確位置,而待排序序列的長度可能只減少1。快速排序通過一趟掃描,就能確保某個數(以它為基準點吧)的左邊各數都比它小,右邊各數都比它大。然後又用同樣的方法處理它左右兩邊的數,直到基準點的左右只有一個元素為止。
幾種排序的時間復雜度,可以參考一下

⑩ 快速排序法

快速排序(Quicksort)是對冒泡排序的一種改進。[1]

快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。[1]

中文名
快速排序演算法
外文名
quick sort
別名
快速排序
提出者
C. A. R. Hoare
提出時間
1960年
快速
導航
排序步驟

程序調用舉例

示例代碼

性能分析
排序流程
快速排序演算法通過多次比較和交換來實現排序,其排序流程如下:[2]
(1)首先設定一個分界值,通過該分界值將數組分成左右兩部分。[2]
(2)將大於或等於分界值的數據集中到數組右邊,小於分界值的數據集中到數組的左邊。此時,左邊部分中各元素都小於或等於分界值,而右邊部分中各元素都大於或等於分界值。[2]
(3)然後,左邊和右邊的數據可以獨立排序。對於左側的數組數據,又可以取一個分界值,將該部分數據分成左右兩部分,同樣在左邊放置較小值,右邊放置較大值。右側的數組數據也可以做類似處理。[2]
(4)重復上述過程,可以看出,這是一個遞歸定義。通過遞歸將左側部分排好序後,再遞歸排好右側部分的順序。當左、右兩個部分各數據排序完成後,整個數組的排序也就完成了。[2]
排序步驟
原理
設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(通常選

快排圖
用數組的第一個數)作為關鍵數據,然後將所有比它小的數都放到它左邊,所有比它大的數都放到它右邊,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。[1]
一趟快速排序的演算法是:[1]
1)設置兩個變數i、j,排序開始的時候:i=0,j=N-1;[1]
2)以第一個數組元素作為關鍵數據,賦值給key,即key=A[0];[1]
3)從j開始向前搜索,即由後開始向前搜索(j--),找到第一個小於key的值A[j],將A[j]和A[i]的值交換;[1]
4)從i開始向後搜索,即由前開始向後搜索(i++),找到第一個大於key的A[i],將A[i]和A[j]的值交換;[1]
5)重復第3、4步,直到i==j; (3,4步中,沒找到符合條件的值,即3中A[j]不小於key,4中A[i]不大於key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i, j指針位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令循環結束)。[1]
排序演示
假設一開始序列{xi}是:5,3,7,6,4,1,0,2,9,10,8。
此時,ref=5,i=1,j=11,從後往前找,第一個比5小的數是x8=2,因此序列為:2,3,7,6,4,1,0,5,9,10,8。
此時i=1,j=8,從前往後找,第一個比5大的數是x3=7,因此序列為:2,3,5,6,4,1,0,7,9,10,8。
此時,i=3,j=8,從第8位往前找,第一個比5小的數是x7=0,因此:2,3,0,6,4,1,5,7,9,10,8。

熱點內容
精準扶貧資料庫 發布:2024-10-11 03:14:13 瀏覽:467
我的世界伺服器被ban改ip有用嗎 發布:2024-10-11 02:32:04 瀏覽:782
rc4加密及解密 發布:2024-10-11 02:31:30 瀏覽:3
安卓手機有什麼免費音樂軟體 發布:2024-10-11 02:17:07 瀏覽:992
阿里雲伺服器須知 發布:2024-10-11 02:12:55 瀏覽:417
androidaaptexe 發布:2024-10-11 01:49:48 瀏覽:348
用手機怎麼連wifi密碼 發布:2024-10-11 01:35:29 瀏覽:59
微信平台無法上傳圖片 發布:2024-10-11 00:55:59 瀏覽:141
加密鎖折斷 發布:2024-10-10 23:57:30 瀏覽:149
上傳活動成果 發布:2024-10-10 23:48:27 瀏覽:189