zoukankan      html  css  js  c++  java
  • 快速排序 两种partition实现

    标签: 算法基础


    1. 算法简介

      快速排序,正如其名字一样,是排序算法中速度较快的一种排序,算法复杂度为(O(n*logn))
      排序过程中会打乱元素的相对位置,是不稳定排序

      算法思想:选定一个pivot,把元素分为两组,一组比pivot小,一组比pivot大,然后按照相同的方法处理这两组元素,是一个递归的过程。

      算法核心是partition方法,即把元素分开两组的方法,每次把元素平均分到两边时,算法效率最高。相反,如果每次partition把元素完全分到一边,是最差情况,算法退化为(O(n^2))

      下面详细介绍两种partition方法。假设需要排序的数组为: 21, 34, 74, 3, 20, 2, 56, 46, 6。

    2. partition1方法

      先把选定为pivot的元素放到最后,然后设定指针low和指针high,low指针左移,high指针右移,当两个指针相撞后停止移动。期间如果符合交换条件,两元素交换。最后把pivot元素放到中间。
      这里选择数组第一个元素作为pivot。

    代码:

    
    /**
      * @arr 待排序的数组
      * @begin 需要partition的起始下标
      * @end 需要partition的末尾下标
      * @return 返回pivot所在位置下标
      */
    int partition1(int arr[], int begin, int end) {
    	int pivotIndex = begin;
    	int pivot = arr[pivotIndex];
    	swap(arr, pivotIndex, end);
    
    	int low = begin;
    	int high = end;
    
    	while (low < high) {
    		// 因为把pivot放在了最后,所以low指针先走
    		while (low < high && arr[low] < pivot) low++; 
    		while (low < high && arr[high] > pivot) high--;
    		if(low < high) swap(arr, low, high);
    	}
    
    	swap(arr, low, end);
    	return low;
    }
    

    3. partition2方法

      类似冒泡排序的思路,把比pivot大的元素“往下沉”,把比pivot小的元素“往上浮”。
      

    代码:

    /**
      * @arr 待排序的数组
      * @begin 需要partition的起始下标
      * @end 需要partition的末尾下标
      * @return 返回pivot所在位置下标
      */
    int partition2(int arr[], int begin, int end){
        int pivotIndex = begin;
        int pivot = arr[pivotIndex];
        swap(arr, pivotIndex, end);
       
        int big = begin - 1; // index of smaller element
        for (int small = begin; small <= end - 1; small++){
            // 遇到一个元素小于pivot
            if (arr[small] <= pivot){
                big++;
                swap(arr, big, small);
            }
        }
        swap(arr, big + 1, end);
        return big + 1;
    }
    

    4.快速排序代码

    
    void quickSort(int[] arr, int begin, int end) {
    	if (begin < end){
    	    int p = partition1(arr, begin, end);
    	    // int p = partition2(arr, begin, end);
    	    quickSort(arr, begin, p - 1);
    	    quickSort(arr, p + 1, end);
    	}
    }
    
    public static void main(String []argc){
        int []array = {21, 34, 74, 3, 20, 2, 56, 46, 6};
        quickSort(array, 0, array.length - 1);
    }
    

    5. 算法优化

    1. 在递归到规模比较小时,使用选择排序/插入排序代替。
    2. 选取一个比较靠谱的pivot。(取first,取last,取middle,取三者的中)
    3. 使用循环代替递归。
  • 相关阅读:
    【移动自动化】【三】控件定位
    【移动自动化】【二】Appium
    【自动化测试:笔记一】adb命令
    mysql api
    计算经纬度的正方形边界
    转 高效的多维空间点索引算法 — Geohash 和 Google S2
    转 为什么geometry+GIST 比 geohash+BTREE更适合空间搜索
    转 HBase GC日志
    转 HBase最佳实践-CMS GC调优
    转:HBase最佳实践-内存规划
  • 原文地址:https://www.cnblogs.com/banyu/p/6660276.html
Copyright © 2011-2022 走看看