排序系列算法——快速排序

快速排序

快速排序描述

快速排序之所以能实现“快速”,是因为采用了分治的策略,分而治之,往往是比线性扫描更加优异的思想。

快速排序可以描述如下:

从要进行排序的序列中找一个元素作为基准的元素V,通过与其他元素进行对比,找到该基准元素所处的位置,然后以该位置为基准将序列分成两个子序列并重复上述的操作。

如:

对序列A={8,4,7,13 ,9,11,5}进行排序,选择第一个元素8为基准元素。

第一步:

通过移动其他元素,寻找基准元素V所属位置

从序列的前后两端开始,先从后往前找出比V小的元素,然后从前往后找出比V大的元素,再交换两者的位置,重复以上操作,直至找不到这样位置。

(1)基准元素为8,将8“拿出来”,8的位置就空了,然后从后往前找到比8小的元素5填补原本8的位置;

 

(2)从前往后找出比8大的元素13,填补当前的空位置,空位置变为元素13原始的位置;

 

(3)从后往前找出比8小的元素6,填补当前的空位置,空位置变为元素6原始的位置;

 

(4)从前往后找出比8大的元素9,填补到当前的空位置,空位置变为9原始的位置;

 

(5)由于所有元素都以及遍历完毕,所以剩余的空位置就是基准元素所属的位置,将基准元素8填补到空位中。

 

第二步:

以基准元素为基准,将序列进行分割成两个序列,基准元素以前的元素是一个序列,以后的元素是令一个序列,对两个序列重复上述1中的工作,直到所有的序列不能进行分割为止

上述的序列分割成两个序列,分别为:

对两个子序列进行第一步所示的工作,当所有的子序列都不能再分时,排序结束。

快速排序的过程与程序的设计

以一个实例模拟快速排序的过程:

设数组A为将要进行排序的数组,A={8,7,13,11,9,6,7,15,10,5}

快排的过程如下:

其中红色字体表示每一段子序列进行排序时所选择的基准元素,蓝色填充色的方块表示已经找到基准元素所处的位置。

 

从上图可以看出,每一个进行排序的序列都要经历三个过程:一是选择则基准元素(上述都选择第一个元素为基准元素),二是对基准元素进行寻址,三是将序列划分成两个子序列并重复上述的工作。

程序设计:

第一步:

选择基准元素value,最简单的方式是选择序列的以一个元素作为基准元素;

第二步:

对基准元素进行寻址,这一步的重点是序列的两头同时往中间寻找元素,从前往后寻找比基准元素小的元素,从后向前寻找比基准元素大的元素,每当找到一个元素将该元素填入空位置,则空位置修改为该元素的原始位置;

令End表示从后向前寻找元素的下标,start表示从前向后寻找元素的下标

(1)由于基准元素的位置是空的,首先先从后往前进行寻找:

While(end>start AND A[end]>= value){           

         end--;                                                               

}

A[start]=A[end];      

由于从后寻找比基准元素小的元素,如果end位置的元素>=value,end往前移动一格,直到找到元素<基准元素。

start为初始的空位置,对start位置赋值,空位置变为end

(2)当前end的位置是空的,从前往后寻找比value值大的元素填补到end的位置上

While(end>start AND A[start]<=value){          

         end++;                                                             

}

A[end]=A[start];       //start为初始的空位置,对start位置赋值,空位置变为end

由于从前往后寻找比基准元素大的元素,如果start位置的元素<=value,start往后移动一格,直到找到元素>基准元素。

start为初始的空位置,对start位置赋值,空位置变为end

(3)重复以上操作,直到start=end为止,此时空位置就是基准元素value的位置。

第三步:

分割成两个子序列重复上述第一步和第二步。

C++版代码实现

 1 #include "stdafx.h"
 2 #include <iostream>
 3 using namespace std;
 4 
 5 void QuickSort(int *values,int startIndex,int endIndex){
 6     int value = *(values+startIndex);
 7     int end=endIndex;
 8     int start=startIndex;
 9     while(end>start){
10         while(end>start&&*(values+end)>value){
11             end--;
12         }
13         *(values+start)=*(values+end);
14         while(end>start&&*(values+start)<=value){
15             start++;
16         }
17         *(values+end)=*(values+start);
18     }
19     *(values+end)=value;
20     if(startIndex<end-1){
21         QuickSort(values,startIndex,end-1);
22     }
23     if(end+1<endIndex){
24         QuickSort(values,end+1,endIndex);
25     }
26 }
27 
28 int main(int argc, _TCHAR* argv[])
29 {
30     int values[]={8,7,13,11,9,6,7,15,10,5,4};
31     QuickSort(values,0,10);
32     for(int i=0;i<11;i++){
33         cout<<*(values+i)<<endl;
34     }
35     return 0;
36 }
原文地址:https://www.cnblogs.com/yonghao/p/5061442.html