zoukankan      html  css  js  c++  java
  • 八大排序之快速排序

    一、基本思想

      快速排序是 一种基于交换的排序算法,是对冒泡排序的改进。它的基本思想是,通过一趟快速排序,将待排记录分割成独立的两部分,其中一部分的关键字均比另一部分小;在分别对这两部分进行排序排序,直至整个序列有序。 

    二、操作步骤

      

      1.将待排记录分隔成独立的两部分,其中一部分的关键字均比另一部分小。选取第一个元素的关键字为支点,即进一次快速排序后,支点左边的元素的关键字均不大于支点的关键字,支点右边的元素的关键字不小于支点的关键字。将这部分操作封装成一个函数。

        1).用一个临时变量储存支点,这样,就有一个空位在左边,即支点的位置,用以存放从右侧选取的小于支点的元素。

        2).从右边开始,寻找比支点大的元素,找到之后将其放到左边的空位上,这样,空位就到右边了,用以存放从左侧选取的大于支点的元素。

        3).从左边开始,寻找比支点小的元素,找到之后将其放到右边的空位上,这样,空位就到了左边,用以存放从右侧选取的小于支点的元素。

        4).重复2)3)操作,知道整个记录遍历。最后将支点放回到空位上。

        进行上述操作后,待排记录就分割成了满足条件的两部分,支点也移动到了合适的位置。

      2.分别对上述两部分继续分割直至区间为一。这是一个递归的过程。

        

    三、实现代码

      测试工具类 点击这里

    package sort;
    
    import sort.util.*;
    
    /*
        快速排序思路:
        1.以某个元素为支点,改变支点位置,使得支点左边的值都不大于它,右边的值都不小于它
        2.对以支点划分的两个区间进行上述操作,直到区间长度为0
        
        时间复杂度:O(nlog2(n)),在数组基本有序时退化为O(n2)
        空间复杂度:O(log2(n)),递归需要栈空间
        稳定性:    不稳定,跳跃式移动
    */
    public class QuickSort implements ISort {
        
        //划分,默认以a[left]为支点,返回划分后支点的位置
        private int partition(int[] a , int left , int right) {
            int t = a[left];                                  
            while(left < right) {                                      //挖坑填数法
                while(left < right && a[right] >= t) {right--;}        //一开始,坑在a[left],所以先找右边符合条件的数来填
                if(left < right) {a[left++] = a[right];}                 //填坑a[left] ,现在坑在a[right]了
                while(left < right && a[left] <= t) {left++;}          
                if(left <right){a[right--] = a[left];}
            } 
            a[left] = t;
            return left;
        }
        
        //递归调用划分,直到区间长度为0
        private void quicksort(int[] a , int left , int right) {       
            if(left < right){
                int dividePoint = this.partition(a , left , right);
                quicksort(a , left , dividePoint - 1);
                quicksort(a , dividePoint + 1 , right);
            }
        }
        
         //便于统一接口回调 
        public void sort(int[] a) {                                  
            this.quicksort(a , 0 , a.length - 1);
        }
        
        public static void main(String[] args) {
            int[] array = RandomArrayGenerator.getRandomArray(100 , 30);
            SortTestHelper.test(new QuickSort() , array);
        }
        
    }

     测试结果:

    四、总结分析

       时间复杂度:O(nlog n ),当待排记录有序时会退化为O(n2)

       空间复杂度:O(1)

       快速排序综合而言是比较优秀的排序算法,但由于跳跃式的记录交换,导致不稳定。

  • 相关阅读:
    第二次公共考试,判断错题集
    云助理里面查询渠道的方法
    公司第二阶段公共考试题
    云助理绑定手机及密码找回方法
    oracle的卸载
    pl/sql进阶--例外处理
    oracle--dba和表的备份与恢复
    oracle触发器
    oracle视图
    pl/sql的介绍
  • 原文地址:https://www.cnblogs.com/wanghang-learning/p/9197865.html
Copyright © 2011-2022 走看看