C C 實現雙路快速排序演算法原理

2022-09-26 10:03:36 字數 3184 閱讀 7132

看了劉宇波的**,講雙路快速排序的,原理講的很直觀,程式講解也一看就懂。這裡寫一下自己的理解過程,也加深一下自己的理解。

首先說一下為什麼需要雙路排序,在有些帶有許多重複資料的陣列裡,使用隨機快速排序或者最簡單的快速排序演算法時,由於重複的資料會放在原來的索引位置不動,就回導致劃分陣列時劃分的某一部分太長,起不到分段排序的效果,這樣就導致演算法退化成o(n^2)的複雜度。就像下圖:

為了解決這個問題,雙路快速排序採用的方法是對等於v的數也進行交換,原理如下所述:

首先選擇乙個數作為標誌,放在陣列的最左側,下標為l,在陣列左邊放小於v的數,右側放大於v的數。

之後,先從l+1開始遍歷陣列,當資料小於v時,該資料屬於左側橙色部分,保持其位置不動,i++,繼續向後遍歷,當找到某個數大於或者等於(注意,這裡等於很重要)v時,停止遍歷。轉而開始根據j來遍歷陣列,j不斷減小,索引陣列的資料,當索引到某個數小於或者等於v時,停止遍歷。如下圖所示:

這時兩個綠色的區域就是分別屬於

之後,將i,j分別向後向前移動一位,繼續開始新的索引,直到i和j重合或者i>j位置,就完成了partition的過程。

下面貼出**:

主函式 main.cpp

// quicksort2.cpp : 雙路快速排序,適用於解決有很多重複資料的陣列。

//#include "stdafx.h"

#include "e:/學習/c++/資料結構和演算法/code/演算法/排序演算法/common/sorttesthelper.h"

#include "quicksort.h"

#include "radomquicksort.h"

#include "quicksort2.h"

using namespace std;

int main()

雙路快速排序演算法 quicksort2.h

#ifndef quicksort2_h

#define quicksort2_h

#include

#include 程式設計客棧iostream>

using namespace std;

template

int __partition3(t *arr, int l, int r)

swap(arr[i], arr[j]);

i++;

j--;

} swap(arr[l], arr[j]);

return j;

}template

void __quicksort2(t *arr,int l,int r)

int p = __partition3(arr, l, r);

__quicksort2(arr, l, p - 1);

__quicksort2(arr, p + 1, r);

}template

void quicksort2(t *arr, int n)

#endif

隨機快速排序 radomquicksort.h

#ifndef radomquicksort_h

#define radomquicksort_h

#include

#include

using namespace std;

template

int __randpartition(t *arr, int l, int r)

int p = __randpartition(arr, l, r);

__radomquicksort(arr, l, p - 1);

__radomquicksort(arr, p + 1, r);

}template

void radomquicksort(t *arr, int n)

#endif

快速排序 quicksort.h

#ifndef quicksort_h

#define quicksort_h

using namespace std;

template

int __partition(t *arr, int l, int r)

int p = __partition(arr, l, r);

__quicksort(arr, l, p - 1);

__quicksort(arr, p + 1, r);

}template

void quicksort(t *arr, int n)

#endif

sorttesthelper 函式

#ifndef sorttesthelper_h

#define sorttesthelper_h

#include

#include

#include

#include

using namespace std;

namespace sorttesthelper

return arr;

}//產生近乎有序的隨機數

int *generatenearlyorderedarray(int n, int swapnum)

for (size_t i = 0; i < swapnum; i++)

return arr;

}//列印陣列:輸入陣列,陣列元素的個數

template

void printarr(t *arr,int n)

std::cout << std::endl;

}//判斷是否已經排序

template

bool ifsort(t *arr,int n) }

return true;

}//計算程式執行時間

template

//函式輸入引數是:所需要計算的執行gyzgcte的函式的名稱,函式的指標,函式的輸入陣列,輸入陣列的個數

void sorttime(string funname,void(*sort)(t*arr, int), t* arr,int n)

{ clock_t startime = clock();

sort(arr,n);

clock_t endtime = clock();

assert(ifsort(arr, n));

std::cout <

最終結果三種演算法對10萬個具有重複的資料的排序時間如下:

本文標題: c/c++實現雙路快速排序演算法原理

本文位址:

Java雙路快速排序演算法

針對序列中重複元素出現頻率非常高,隨機化快速排序演算法退化成o n 2 的問題 雙向開始遍歷 當arr i arr l arr j arr l 時暫停 進行歸併 arr i 與arr j 交換元素 當i j時遍歷完畢 雙路快速排序演算法,對解決重複性高的元素集合效率高 public static s...

C 實現快速排序 雙路快速排序 三路快速排序

從左向右依次遞迴 如果 陣列中的元素都相等,就會變成 n 級別的複雜度演算法 public class quicksort public static void sort t arr where t system.icomparable public static void sort2 t arr ...

雙路快速排序

雙路快速排序的時間複雜度為o nlog2n 空間複雜度為o n 雙路快速排序的核心思想 單路快排會將等於v的元素分配在左側或者右側,當陣列中有大量重複元素時,這將會導致左右兩側的元素數量極度不均衡,時間複雜度退化到o n 2 如下圖所示 雙路快排是將等於v的部分近乎平均的分配在左右兩側,避免了該問題...