• 十大经典排序算法(六、快速排序)


    动图演示

    快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。

    快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。

    算法步骤

    1. 从数列中挑出一个元素,称为 "基准"(pivot);

    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

    JavaScript

     1 function quickSort(arr, left, right) {
     2     var len = arr.length,
     3         partitionIndex,
     4         left = typeof left != 'number' ? 0 : left,
     5         right = typeof right != 'number' ? len - 1 : right;
     6 
     7     if (left < right) {
     8         partitionIndex = partition(arr, left, right);
     9         quickSort(arr, left, partitionIndex-1);
    10         quickSort(arr, partitionIndex+1, right);
    11     }
    12     return arr;
    13 }
    14 
    15 function partition(arr, left ,right) {     // 分区操作
    16     var pivot = left,                      // 设定基准值(pivot)
    17         index = pivot + 1;
    18     for (var i = index; i <= right; i++) {
    19         if (arr[i] < arr[pivot]) {
    20             swap(arr, i, index);
    21             index++;
    22         }        
    23     }
    24     swap(arr, pivot, index - 1);
    25     return index-1;
    26 }
    27 
    28 function swap(arr, i, j) {
    29     var temp = arr[i];
    30     arr[i] = arr[j];
    31     arr[j] = temp;
    32 }
    33 function partition2(arr, low, high) {
    34   let pivot = arr[low];
    35   while (low < high) {
    36     while (low < high && arr[high] > pivot) {
    37       --high;
    38     }
    39     arr[low] = arr[high];
    40     while (low < high && arr[low] <= pivot) {
    41       ++low;
    42     }
    43     arr[high] = arr[low];
    44   }
    45   arr[low] = pivot;
    46   return low;
    47 }
    48 
    49 function quickSort2(arr, low, high) {
    50   if (low < high) {
    51     let pivot = partition2(arr, low, high);
    52     quickSort2(arr, low, pivot - 1);
    53     quickSort2(arr, pivot + 1, high);
    54   }
    55   return arr;
    56 }

    Python

     1 def quickSort(arr, left=None, right=None):
     2     left = 0 if not isinstance(left,(int, float)) else left
     3     right = len(arr)-1 if not isinstance(right,(int, float)) else right
     4     if left < right:
     5         partitionIndex = partition(arr, left, right)
     6         quickSort(arr, left, partitionIndex-1)
     7         quickSort(arr, partitionIndex+1, right)
     8     return arr
     9 
    10 def partition(arr, left, right):
    11     pivot = left
    12     index = pivot+1
    13     i = index
    14     while  i <= right:
    15         if arr[i] < arr[pivot]:
    16             swap(arr, i, index)
    17             index+=1
    18         i+=1
    19     swap(arr,pivot,index-1)
    20     return index-1
    21 
    22 def swap(arr, i, j):
    23     arr[i], arr[j] = arr[j], arr[i]

    C语言

     1 void swap(int *x, int *y) {
     2     int t = *x;
     3     *x = *y;
     4     *y = t;
     5 }
     6 
     7 void quick_sort_recursive(int arr[], int start, int end) {
     8     if (start >= end)
     9         return;
    10     int mid = arr[end];
    11     int left = start, right = end - 1;
    12     while (left < right) {
    13         while (arr[left] < mid && left < right)
    14             left++;
    15         while (arr[right] >= mid && left < right)
    16             right--;
    17         swap(&arr[left], &arr[right]);
    18     }
    19     if (arr[left] >= arr[end])
    20         swap(&arr[left], &arr[end]);
    21     else
    22         left++;
    23     if (left)
    24         quick_sort_recursive(arr, start, left - 1);
    25     quick_sort_recursive(arr, left + 1, end);
    26 }
    27 
    28 void quick_sort(int arr[], int len) {
    29     quick_sort_recursive(arr, 0, len - 1);
    30 }

    C++

     1 template <typename T>
     2 void quick_sort_recursive(T arr[], int start, int end) {
     3     if (start >= end)
     4         return;
     5     T mid = arr[end];
     6     int left = start, right = end - 1;
     7     while (left < right) { //在整个范围内搜寻比枢纽元值小或大的元素,然后将左侧元素与右侧元素交换
     8         while (arr[left] < mid && left < right) //试图在左侧找到一个比枢纽元更大的元素
     9             left++;
    10         while (arr[right] >= mid && left < right) //试图在右侧找到一个比枢纽元更小的元素
    11             right--;
    12         std::swap(arr[left], arr[right]); //交换元素
    13     }
    14     if (arr[left] >= arr[end])
    15         std::swap(arr[left], arr[end]);
    16     else
    17         left++;
    18     quick_sort_recursive(arr, start, left - 1);
    19     quick_sort_recursive(arr, left + 1, end);
    20 }
    21 template <typename T> //整數或浮點數皆可使用,若要使用物件(class)時必須設定"小於"(<)、"大於"(>)、"不小於"(>=)的運算子功能
    22 void quick_sort(T arr[], int len) {
    23     quick_sort_recursive(arr, 0, len - 1);
    24 }
  • 相关阅读:
    Spring Boot Common application properties(转载)
    SVN中trunk,branches,tags用法详解(转载)
    约定优于配置
    JavaScript封装一个MyAlert弹出框
    JavaScript封装一个实用的select控件
    JavaScript的8行代码搞定js文件引入问题
    JavaScript处理数据完成左侧二级菜单的搭建
    SpringMVC+Mybatis实现的Mysql分页数据查询
    十步完全理解 SQL(转载)
    sql语句练习50题
  • 原文地址:https://www.cnblogs.com/wangchaoguo-li/p/14205777.html
Copyright © 2020-2023  润新知