重整算法第四天:快速理解和上手快速排序算法


title: 重整算法第四天:快速理解和上手快速排序算法
date: 2019-04-11
tags: 算法

重整算法第四天:快速理解和上手快速排序算法

原作者:濤聲依舊,微信公衆號“趣味編程”
原文章鏈接:圖解冒泡排序

快速排序,顧名思義,是一種排序速度非常快的排序方法,該算法之所以很快是因爲高度優化的內部循環。

快速排序是一種採用分治思想,在實踐中通常運行較快的一種排序算法,思路如下:

對於一個無序數組
在這裏插入圖片描述

首先,任意選取一個元素,通常選取數組的第一個元素,該元素成爲中軸元素
在這裏插入圖片描述

然後將大於或者等於中軸元素的元素放在右邊,小於或者等於中軸元素的元素放在左邊

上面兩個過程,選元素和調整位置成爲分割(partition)
在這裏插入圖片描述

然後對左右兩個子數組分別按照同樣的方法進行分割操作(遞歸進行)
一直遞歸分割到子數組只有一個或者零個元素爲止,此時整個數組有序
在這裏插入圖片描述

分割操作的進行過程:
首先,用兩個變量i和j從數組兩邊開始向中間掃描,i從右走,j從左走
在這裏插入圖片描述

i初始化爲第一個元素的下標,j初始化爲最後一個元素的下標加1

i往右走,直到遇見比中軸元素大的(或等於)元素停止移動,j向左走,直到遇到比中軸元素小的(或等於)的元素停止移動。
在這裏插入圖片描述

此時,如果i<j,則交換i,j所指向的元素
在這裏插入圖片描述

然後繼續向右走向左走,直到i>=j,整個掃描停止
在這裏插入圖片描述

此時i對應元素的左邊(不包含arr[i])必定小於或等於5,j對應元素的右邊(不包含arr[j])必定大於或等於5

交換中軸元素5與arr[j]

在這裏插入圖片描述

分割完成

對數組arr[low…high]進行快速排序

首先進行分割操作,返回中軸元素下標j,然後對左數組arr[low…j-1]和右數組arr[j+1…high]分別遞歸進行排序

什麼時候遞歸終止?當然是數組大小爲小於等於1(0或1)時

代碼如下

package com.lagoon.sort;

import java.util.Arrays;

/**
 * @Author WinkiLee
 * @Date 2019/4/12 15:35
 * @Description
 */
public class QuickSort {

    /**
     * 對數組arr[low...high]進行快速排序
     */
    private static void quickSort(int[] arr, int low, int high) {

        //數組小於等於1時遞歸終止,否則對數組進行排序
        if (low < high) {
            //對數組arr[low...high]進行分割,返回中軸元素下標
            int j = partition(arr, low, high);

            //對左數組arr[low...j-1]進行快速排序
            quickSort(arr, low, j - 1);

            //對右數組arr[j+1...high]進行快速排序
            quickSort(arr, j + 1, high);
        }
    }


    /**
     * 選出中軸元素,將數組arr[low..high]分割成三部分
     * arr[low...j-1]<=arr[j]<=arr[j+...high]
     *
     * @param arr
     * @param low
     * @param high
     * @return
     */
    private static int partition(int[] arr, int low, int high) {
        /**
         * 左右掃描指針
         */
        int i = low, j = high + 1;

        /**
         * 中軸元素v
         */
        int v = arr[low];

        //i,j掃描數組
        while (true) {
            //遇到比中軸元素v大的(或等於)元素時(break)
            while (arr[++i] < v) {
                if (i == high) {
                    break;
                }
            }
                while (arr[--j] > v) {
                    if (j == low) {
                        break;
                    }
                }
                //如果i>=j,掃描結束
                if (i >= j) {
                    break;
                } else {
                    exch(arr, i, j);
                }
        }
        exch(arr, low, j);
        return j;
    }

    /**
     * 交換數
     *
     * @param a
     * @param i
     * @param j
     */
    private static void exch(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    /**
     * main方法
     */
    public static void main(String[] args) {
        int[] arr=new int[]{5,1,2,8,4,9,7,10,0,14,22};
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
}

運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章