zoukankan      html  css  js  c++  java
  • 排序算法 快速排序详解

    1、快速排序的简单介绍

      算法思想:基于分治的思想,是冒泡排序的改进型。首先在数组中选择一个基准点(该基准点的选取可能影响快速排序的效率,后面讲解选取的方法),然后分别从数组的两端扫描数组,设两个指示标志(low指向起始位置,high指向末尾),首先从后半部分开始,如果发现有元素比该基准点的值小,就交换low和high位置的值,然后从前半部分开始扫秒,发现有元素大于基准点的值,就交换low和high位置的值,如此往复循环,直到low>=high,然后把基准点的值放到high这个位置。一次排序就完成了。以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。

    2、快速排序算法的特点

    • 快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较;
    • 最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n*n);
    • 在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlogn);
    • 尽管快速排序的最坏时间为O(n*n),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlogn)。

    3、快速排序算法的代码实现

    复制代码
     1 package com.baozi.paixu;
     2 
     3 import java.util.Arrays;
     4 
     5 /**
     6  * 快速排序:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别
     7  * 对这两部分继续进行排序,直到整个序列有序。
     8  *
     9  *
    11  */
    12 public class QuickSort {
    13     public static void main(String[] args) {
    14         final int MAX = 15;
    15         int[] nums = new int[MAX];
    16         System.out.println("...............使用的是选择排序算法...............");
    17         for (int i = 0; i < MAX; i++) {
    18             nums[i] = (int) (Math.random() * 10 + 5);
    19         }
    20         System.out.println("排序之前的数组为...............");
    21         System.out.println(Arrays.toString(nums));
    22         System.out.println("排序之后的数组为...............");
    23         //使用选择排序算法进行排序:
    24         QuickSort sort = new QuickSort();
    25         sort.quickSort(nums, 0, nums.length - 1);
    26         System.out.println(Arrays.toString(nums));
    27     }
    28 
    29     public void quickSort(int[] nums, int low, int high) {
    30         if (low < high) {
    31             int middle = getMiddle(nums, low, high);
    32             //对左子序列进行排序
    33             quickSort(nums, low, middle - 1);
    34             //对右子序列进行排序
    35             quickSort(nums, middle + 1, high);
    36         }
    37     }
    38 
    39     private int getMiddle(int[] nums, int low, int high) {
    40         //当前数组的第一个元素作为中轴(基准)
    41         int temp = nums[low];
    42         while (low < high) {
    43             //这里temp <= nums[high]中等号的情况相当于数组中出现了两个相等的数字,循环比较依然能够继续
    44             while (low < high && temp <= nums[high]) {
    45                 high--;
    46             }
    47             nums[low] = nums[high];
    48             while (low < high && temp >= nums[low]) {
    49                 low++;
    50             }
    51             nums[high] = nums[low];
    52         }
    53         nums[low] = temp;
    54         return low;
    55     }
    56 }
    复制代码
  • 相关阅读:
    HDU 1114 Piggy-Bank
    HDU 2955 Robberies
    NTOJ 290 动物统计(加强版)
    POJ 3624 Charm Bracelet
    HDU 2602 Bone Collector
    POJ 1523 SPF(无向图割顶)
    HDU 5311 Hidden String
    HDU 1421 搬寝室
    HDU 1058 Humble Numbers
    POJ 3259 Wormholes(spfa判负环)
  • 原文地址:https://www.cnblogs.com/Transkai/p/11532909.html
Copyright © 2011-2022 走看看