快速排序的基本实现

快速排序算法是一种基于交换的高效的排序算法,它采用了分治法的思想:

1、从数列中取出一个数作为基准数(枢轴,pivot)。 

2、将数组进行划分(partition),将比基准数大的元素都移至枢轴右边,将小于等于基准数的元素都移至枢轴左边。

3、再对左右的子区间重复第二步的划分操作,直至每个子区间只有一个元素。

快排最重要的一步就是划分了。划分的过程用通俗的语言讲就是“挖坑”和“填坑”。

快速排序时间复杂度

快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*lgN)

这句话很好理解:假设被排序的数列中有N个数。遍历一次的时间复杂度是O(N),需要遍历多少次呢?至少lg(N+1)次,最多N次。
(01) 为什么最少是lg(N+1)次?快速排序是采用的分治法进行遍历的,我们将它看作一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的定义,它的深度至少是lg(N+1)。

因此,快速排序的遍历次数最少是lg(N+1)次。
(02) 为什么最多是N次?这个应该非常简单,还是将快速排序看作一棵二叉树,它的深度最大是N。因此,快读排序的遍历次数最多是N次。

快速排序稳定性
快速排序是不稳定的算法,它不满足稳定算法的定义。
算法稳定性 — 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!

快速排序 实现一:

 1 int partition(int arr[], int left, int right)  //找基准数 划分
 2 {
 3     int i = left + 1 ;
 4     int j = right;
 5     int temp = arr[left];
 6 
 7     while(i <= j)
 8     {
 9         while (arr[i] < temp)
10         {
11             i++;
12         }
13         while (arr[j] > temp )
14         {
15             j--;
16         }
17         if (i < j)
18             swap(arr[i++], arr[j--]);
19         else i++;
20     }
21     swap(arr[j], arr[left]);
22     return j;
23 
24 }
25 
26 void quick_sort(int arr[], int left, int right) 
27 {
28     if (left > right)
29         return;
30     int j = partition(arr, left, right);
31     quick_sort(arr, left, j - 1);
32     quick_sort(arr, j + 1, right);
33 }

快速排序 实现方法二:

 1 void QuickSort(int array[], int start, int last)
 2 {
 3     int i = start;
 4     int j = last;
 5     int temp = array[i];
 6     if (i < j)
 7     {
 8         while (i < j)
 9         {
10             //
11             while (i < j &&  array[j]>=temp )
12                 j--;
13             if (i < j)
14             {
15                 array[i] = array[j];
16                 i++;
17             }
18 
19             while (i < j && temp > array[i])
20                 i++;
21             if (i < j)
22             {
23                 array[j] = array[i];
24                 j--;
25             }
26                         
27         }
28         //把基准数放到i位置
29         array[i] = temp;
30         //递归方法
31         QuickSort(array, start, i - 1);
32         QuickSort(array, i + 1, last);
33     }
34 }

快速排序 用C++函数模板实现

 1 template<typename T>
 2 void quicksort(T data[], int first, int last)
 3 {
 4     int lower = first + 1;
 5     int upper = last;
 6     swap(data[first], data[(first + last) / 2]);
 7     T bound = data[first];
 8     while (lower <= upper)
 9     {
10         while (data[lower] < bound)
11             lower++;
12         while (data[upper] > bound)
13             upper--;
14         if (lower < upper)
15             swap(data[lower++], data[upper--]);
16         else lower++;
17     }
18     swap(data[upper], data[first]);
19     if (first < upper - 1)
20         quicksort(data, first, upper - 1);
21     if (upper + 1 < last)
22         quicksort(data, upper + 1, last);
23 }
24 
25 template<class T>
26 void quicksort(T data[], int n)
27 {
28     int i, max;
29     if (n < 2)
30         return;
31     for (i = 1, max = 0; i < n; i++)
32         if (data[max] < data[i])
33             max = i;
34     swap(data[n - 1], data[max]);
35     quicksort(data, 0, n - 2);  //  
36 }

快速排序  主函数测试代码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
using namespace std;

void PrintArray(int array[], int len)
{
    for (int i = 0; i < len; i++)
    {
        cout << array[i] << " ";
    }
    cout << endl;
}

int main(void)
{
    const int NUM = 10;
    int array[NUM] = { 0 };
    srand((unsigned int)time(nullptr));
    for (int i = 0; i < NUM; i++)
    {
        array[i] = rand() % 100 + 1;
    }
    cout << "排序前:" << endl;
    PrintArray(array, NUM);
    cout << "排序后:" << endl;
    quicksort(array, 0, NUM - 1);
        PrintArray(array, NUM);

    return 0;
}    

 

版权声明:本文为miracleswgm原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/miracleswgm/p/9199124.html