談談快速排序

前言

本文章主要講解快速排序的原理以及代碼實現。算法

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

分治法的簡述

分治法是指將一個難以直接解決的大問題,劃分紅一些規模較小的子問題,以便各個擊破,分而治之。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

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

相關文章
相關標籤/搜索