语言库中常用的排序算法qsort()底层结构

  • 优先使用归并排序(因为归并排序空间复杂度是O(n),并且是稳定排序算法,时间复杂度O(nlogn))
  • 当需排序的数据量比较大的时候,改为使用优化快排(比如三数取中获取分区点)
  • 当快排时,排序的元素个数小于7时,快排退化为插入排序
  传统的快排算法,由于分区点选的不好,可能就会导致算法效率过低。常用分区算法有三数取中法、随机法等。所以可对传统快排进行以下优化
  • 优化1:三数取中
  • 优化2:去掉不必要的交换mySwap(),直接改为替换
#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include "TreeNode.h"
#include "ListNode.h"
using namespace std;

void mySwap(int num[], int i, int j){
    int temp = num[i];
    num[i] = num[j];
    num[j] = temp;
}

// 优化快排算法
// 传统的快排算法,由于分区点选的不好,可能就会导致算法效率过低
// 常用分区算法(三数取中法、随机法)
// 优化1:三数取中
// 优化2:去掉不必要的交换mySwap()
int Partition(int num[], int start, int end){

    int m = start + (end - start)/2;
    if(num[start] > num[end])
        // 交换左端与右端数据,保证左端较小
        mySwap(num, start, end);
    if(num[m] > num[end])
        // 交换中间与右端数据,保证中间较小
        mySwap(num, m, end);
    if(num[m] > num[start])
        // 交换中间与左端数据,保证左端较小
        mySwap(num, start, m);

    // 经过交换之后,左端数据为左中右中间值
    int pivotkey = num[start];

    while(start < end){
        // 从右到左找到扫描
        while(start < end && num[end] >= pivotkey)
            end--;
        // 将交换改为替换
        num[start] = num[end];

        while(start < end && num[start] <= pivotkey)
            start++;
        // 将交换改为替换
        num[end] = num[start];
    }
    // 将分区值替换为num[start]或者num[end],因为此时start=end
    num[start] = pivotkey;
    return start;
}

void QuickSort(int num[], int start, int end){
    if(start >= end)
        return ;

    int pivotkey = Partition(num, start, end);
    QuickSort(num, start, pivotkey - 1);
    QuickSort(num, pivotkey + 1, end);
}

int main(int argc, char* argv[]){

    int arr[8] = {8,7,6,5,4,3,2,1};
    QuickSort(arr, 0, 7);
    for(int i = 0; i < 8; i++){
        cout<<arr[i]<<"	";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/flyingrun/p/13420319.html