快速排序的思想(以從小到大爲例)
(1)第一次排序
選取數組內的一個元素作爲標準,將數組分爲兩部分;將小於該標準的元素存放在該標準的左邊,大於該標準的元素放在右邊,完成第一次排序;
(2)第二次排序
對分割後的兩部分數組分別進行排序(遞歸的調用)。
基本方法
1)創建函數,傳遞的參數分別是數組的地址,數組首個元素的位置,數組元素的末位置;
2)在函數中聲明三個變量x、begin、end(x用來取爲標準元素,begin、end分別用來接收傳參的後兩個數值作爲記錄循環的位置);
3)我先將數組的首個元素作爲標準元素(即x=str[begin]),先從數組的末位置開始與x進行比較,如果小於x則進行交換;再從數組的首位置開始與x進行比較,如果大於x則進行交換,直到begin>=end;完成第一次排序;
4)前三個步驟完成後,數組被分爲兩部分:一部分是小於標即準元素,一部分是大於標準元素。將左右兩部分分別進行排序(即調用創建的函數),完成第二次排序。
例:待排序的數組str:42,25,56,34,21
#include<stdio.h>
#include<stdlib.h>
void QuickSort(int str[],int i,int j)
{
int begin=i,end=j;
int x=str[i];
if(begin<end)
{
while(begin<end)
{
while(begin<end&&str[end]>x)
end--;
if(begin<end)
str[begin++]=str[end];
while(begin<end&&str[begin]<x)
begin++;
if(begin<end)
str[end--]=str[begin];
}
str[begin]=x;
QuickSort(str,i,end-1);//用遞歸將選取的標準數左右兩邊都進行排序
QuickSort(str,begin+1,j);
}
}
int main()
{
int str[5]={42,25,56,34,21};
int i=0,j=4;
QuickSort(str,i,j);
for(i=0;i<5;i++)
printf("%3d",str[i]);
}
基本方法2
第二種方法與第一種方法的思路大致相同,兩者的區別在於交換數據的時候,第一種是先在右邊開始找到第一個交換的數字,在交換後再從左邊進行交換,通過x記錄了被覆蓋的str[0],直到i=j;第二種方法因爲選擇的也是str[0]作爲標準,然後也是右邊即end先走找到小於str[0]的數字後,begin再開始走,直到找到大於str[0]的數字,用三步法進行交換,這種方法比較簡單易懂。
例:待排序的數組str:42,2556,34,21
#include<stdio.h>
#include<stdlib.h>
void QuickSort(int str[],int i,int j)
{
int begin=i,end=j;
int x=str[i];
if(begin > end) return;
while(begin<end)
{
while(begin<end&&str[end]>x)
end--;
while(begin<end&&str[begin]<x)
begin++;
if(begin<end)
{
int temp=str[end];
str[end]=str[begin];
str[begin]=temp;
}
QuickSort(str,i,begin - 1);
QuickSort(str,end + 1,j);
}
}
int main()
{
int str[]={42,25,56,34,21};
int i=0,j=4;
QuickSort(str,i,j);
for(i=0;i<5;i++)
printf("%3d",str[i]);
return 0;
}
快速排序的作用
相對於冒泡排序而言,每次交換都是跳躍式的,不像冒泡排序一樣只能在相鄰的兩個數之間進行交換,交換的次數較少,提高了程序的運行速度。在最差的情況下,時間複雜度仍和冒泡排序一樣是O(N^2),但是平均複雜度是O(NlonN)。