谈谈快速排序

前言

本文章主要讲解快速排序的原理以及代码实现。算法

快速排序基于的思想(分治法)

分治法的简述

分治法是指将一个难以直接解决的大问题,划分红一些规模较小的子问题,以便各个击破,分而治之。bash

image

分治法的求解过程

分治法求解问题的主要步骤:划分,求解,合并。ui

(1)问题划分。将规模为n的问题划分红k个子问题;spa

(2)求解子问题。各子问题的求解方法相同,一般采用递归方法实现;3d

(3)合并子问题的解。将各子问题的解逐层合并,获得问题的最终解。code

快速排序的分治策略

(1)划分:选定一个记录做为轴值,以轴值为基准将整个序列划分为两个子序列r1… ri-1和ri+1 … rn,前一个子 序列中记录的值均小于或等于轴值,后一个子序列中记录的值均大于或等于轴值;cdn

(2)求解子问题:分别对划分后的每个子序列递归处理;blog

(3)合并:因为对子序列r1 … ri-1和ri+1 … rn的排序是就地进行的,因此合并不须要执行任何操做。排序

image

举例子说明

对序列[23,13,35,6,19,50,28]进行快速排序的过程。(注意:这里以第一个记录做为轴值,黑体表明轴值)递归

一次划分过程,以下图:

image

以轴值为基准将待排序序列划分为两个子序列后,对每个子序列分别递归进行处理,下图是一个快速排序的完整的例子。

image

算法实现

int Partition(int r[ ], int first, int end)
 {
      int i=first, j=end;         //初始化
      int temp;
   
       while (i<j)
       {  
           while (i<j && r[i]<= r[j]) 
               j--;        //右侧扫描
           if (i<j) { 
               temp=r[i]; r[i]=r[j]; r[j]=temp;   //将较小记录交换到前面
               i++; 
           }
           while (i<j && r[i]<= r[j]) 
               i++;     //左侧扫描 
               if (i<j) {
                  temp=r[i]; r[i]=r[j]; r[j]=temp;   //将较大记录交换到后面
                  j--; 
               }
           }
      return i;      // i为轴值记录的最终位置
 }


void QuickSort(int r[ ], int first, int end) 
{  
   int mid; //划分后的轴值位置
  
   if (first < end) {      
     mid = Partition(r, first, end);     //划分,mid是轴值在序列中的位置
     QuickSort(r, first, mid-1);        //求解子问题1,对左侧子序列进行快速排序
     QuickSort(r, mid+1, end);          //求解子问题2,对右侧子序列进行快速排序
   }
}
复制代码

快速排序时间复杂度和空间复杂度分析

image

注意:一个序列基本有序用快速排序反而是不合适的!

相关文章
相关标签/搜索