快速排序算法
本文参考清华大学出版社《数据结构与算法(C语言版)(第三版)》,详情请见书本。
        快速排序是已知排序算法中速度最快的。
        快速排序对序列S进行排序分成以下4步:
           (1)如果S中只有1或者0个元素,则返回。
           (2)在S中任意取一个元素v,称为枢纽元(pivot)。
           (3)将S-{v}分成两个不相交的集合:S1={χ∈S-{v}|χ≤v}和S2={χ∈S-{v}|χ>v}。
           (4)返回排序结果:{quicksort(S1),v,quicksort(S2)}。
        下图以例子:{5,6,2,20,8,12,16,18,1}为例,讲解算法过程:
                                              
        
        选取枢纽元的好坏,关系到算法性能的好坏。
        常见的选取枢纽元的方法:
            ①选择待排序序列的第一个或最后一个记录。弊端:大段序列已经预排序,使得划分的子集严重失衡。
            ②使用随机数发生器来随机选取枢纽元。弊端:产生随机数本身要花费时间。
            ③实际中常见的三数中值分割法。用任意3个数值的中值作为整个序列中值的估量值。取待排序序列的第一个记录,位置位于中间的记录和最后一个记录的中值作为枢纽元。
         待排序序列为{5,6,2,20,8,12,16,18,1},取record[0]=5, record[4]=8, record[8]=1的中值8为枢纽元。
         三数中值分割法获取枢纽元的算法:获取枢纽元,并将其放在待排序记录的最后。
   int getPivot(int *SList, int left, int right)
   {
     int center=(left+right)/2;
     if(SList[left]>SList[center])
         swap(&SList[left], &SList[center]);
     if(SList[left]>SList[right])
         swap(&SList[left], &SList[right]);
     if(SList[center]>SList[right])
         swap(&SList[center], &SList[right]);
     swap(&SList[center], &SList[right]);
     //将pivot放在倒数第一的位置,除了可以得到pivot的右值,还能得到其左值
     return SList[right-1];
   }       对集合的分割策略:集合分割策略演示:
                                             
      快速排序算法:
   int quicksort(int *SList, int left, int right)
   {
     if(right-left>=3)
     {
       int pivot,i,j;
       pivot = getPivot(SList,left,right);
       i=left;
       j=right;
       while(true)
       {
         while(SList[i]<pivot)
           i++;
         while(Slist[j]>pivot)
           j--;
         if(i<j)
           swap(&SList[i],&SList[j]);
         else
           break;
       }
       swap(&SList[i],&SList[right]);
       quicksort(SList, left, i-1);
       quicksort(SList, i+1, right);
     }
     else     //当待排序序列长度小于3时使用直接插入排序
       straightsort(SList, right-left);
   }        快速排序实现程序:
在VS2010下新建Win32 控制台应用程序的项目:QuickSort
见下图:
                                    
源代码:QuickSort.cpp
// QuickSort.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<stdio.h>
#define MAXSIZE 20
  int Partition(int *SList, int low, int high)
  {
    int pivotkey=SList[low];
    while(low<high)
    {
      while(low<high && SList[high]>=pivotkey)
        high--;
      SList[low]=SList[high];
      while(low<high && SList[low]<=pivotkey)
        high++;
      SList[high]=SList[low];
    }
    SList[low]=pivotkey;
    return low;
  }
  void QSort(int *SList, int low, int high, int len)
  {
     int pivotloc;
     if(low<high)
     {
        int i;
        for(i=0; i<len; i++)
        {
          printf("%d ", SList[i]);
        }
        pivotloc=Partition(SList, low, high);
        printf("(Current pivotkey is %d) ", SList[pivotloc]);
        for(i=0; i<len; i++)
        {
          printf("%d ", SList[i]);
        }
        printf("\n ");
        QSort(SList, low, pivotloc-1, len);
        QSort(SList, pivotloc+1, high, len);
     }
  }
  void QuickSort(int *SList, int len)
  {
     QSort(SList, 0, len-1, len);
  }
  int main()
  {
    int length;
    //int pos;
    int test[MAXSIZE];
    int i;
    printf("Please input the number of record:\n");
    if(scanf("%d",&length)!=1)
      return -1;
    printf("Please input the record:\n");
    for(i=0; i<length; i++)
    {
       scanf("%d",&(test[i]));
    }
    QuickSort(test,length);
    for(i=0; i<length; i++)
    {
       printf("%d ", test[i]);
    }
    printf("\n ");
    return 0;
  }
      Ctrl+F5执行QuickSort.cpp ,运行结果如下:
                          
原文:http://blog.csdn.net/wp1603710463/article/details/51002267