快速排序法的總結
今天終於從《征服c指針》這本書看到了早有耳聞的快速排序法,以前學過選擇排序,交換排序,冒泡排序,今天又多了一種排序算法。書中作者講到測試對5萬個隨機整數進行排序,冒泡排序花了117秒,而快速排序僅僅用了65毫秒。哎,果真算法正重要啊!
一開始看《征服c指針》的快速排序的交換法感覺沒怎麼看懂,於是上網找了篇好文“原文地址http://blog.csdn.net/morewindows/article/details/6684558”的白話經典算法系列,其中介紹的填坑式快速排序倒是很容易懂,代碼如下
#include<stdio.h>
#include<stdlib.h>
void quicksort(int s[] ,int left,int right)//快速排序算法
{
if(left<right)
{
int key=s[left];//關鍵值設爲左邊第一個數
int i=left,j=right;
while(i<j)
{
while(i<j&&s[j]>key)//從右開始尋找比key小的值
{
j--;
}
if(i<j)
{
s[i]=s[j];//將s[j]的值賦給s[i],此時s[j]爲一個坑
i++;
}
while(i<j&&s[i]<key)//從左往右尋找比key大的值
{
i++;
}
if(i<j)
{
s[j]=s[i];//將s[i]的值賦給s[j],將s[j]之前玩的坑填上
}
}
//如果i=j,這輪分堆分完,將key填給s[i]
s[i]=key;
//遞歸
quicksort(s,left,i-1);
quicksort(s,i+1,right);
}
}
int main()
{
int i;
int s[]={1,4,5,6,3,2,9};
quicksort(s,0,6);//數組長度記得減1
for (i=0;i<sizeof(s)/sizeof(int);i++)
{
printf("%d\t",s[i]);
}
return 0;
}
這種算法是將數組的第一個元素就設爲key值,即中間值,然後從右尋找比key小的值,找到後停下,將找到的s[j]賦給s[i]即第一個元素,此時s[j]可以看作是一個坑,什麼東西也沒有,再從左邊尋找比key大的值,找到後停下(前提i<j),然後將此值把s[j]這個坑下,重複此操作,直到i=j(i最後必定等於j),此時將key值賦給s[i]或s[j],完成第一輪分堆操作,此後遞歸調用再分左堆和右堆。
下面這個算法是《征服c指針》給出的:
#include<stdio.h>
#include<stdlib.h>
#define SWAP(a,b) {int temp;temp=a;a=b;b=temp;}
void quicksort2(int *s,int left,int right)
{
int l=left,r=right;
int key=(s[l]+s[r])/2;
while(l<=r)
{
for(;s[l]<key;l++)//從左尋找
;
for(;s[r]>key;r--)//從右尋找
;
if(l<=r)
{
SWAP(s[l],s[r]);
l++;
r--;//這個操作是進行下一輪交換的預備
}
}
//從循環出來後說明一輪分堆已完成
if(r>left)//遞歸左堆
{
quicksort2(s,left,r);
}
if(l<right)//遞歸右堆
{
quicksort2(s,l,right);
}
//不滿足條件即退出
}
int main()
{
int i;
int s[]={1,4,5,6,3,2,9};
quicksort2(s,0,6);//數組長度記得減1
for (i=0;i<sizeof(s)/sizeof(int);i++)
{
printf("%d\t",s[i]);
}
return 0;
}
這種算法我目前還沒完全掌握,與上一個其實是殊途同歸,只不過不是填坑而是交換了。
我覺得目前其實都還沒完全掌握快速排序,主要是還沒實戰過,代碼寫少了,既然這種排序算法更優,那麼以後多用這種算法來排序。