Java排序算法分析與實現:快排、冒泡排序、選擇排序、插入排序、歸並排序(二)


一、概述:

  上篇博客介紹了常見簡單算法:冒泡排序、選擇排序和插入排序。本文介紹高級排序算法:快速排序和歸並排序。在開始介紹算法之前,首先介紹高級算法所需要的基礎知識:划分、遞歸,並順帶介紹二分查找算法。

二、划分:

  划分是快速排序的前提,即把數據分為兩組,大於特定值的數據在一組,小於特定值的數據在另一組。快速排序即是由划分和遞歸操作來完成的。

(1)原理:

  定義一個閾值,分別從最左面和最右面向中間遍歷元素,左面找到一個大於閾值的數據便停止,右邊找到一個小於閾值的數據便停止,如果此時左右兩邊都還沒有走到中間,則交換左面大於閾值的數據和右面小於閾值的數據;重復上述過程,直到左面指針和右面指針相遇,此時左面數據均小於閾值,右面數據均大於閾值,划分結束。划分結束后,數據仍然是無序的,但更接近於有序。

(2)例子:

  待划分數據:7, 6, 9, 8, 5,1,假設閾值為5

  第一輪:左指針指向7,右指針指向1,左指針向后移,右指針向左移,發現左面第一個大於5的元素7,右面第一個小於5的元素1,交換7和1的位置,結果:1,6,9,8,5,7;

  第二輪:從6開始找大於5的數字,找到6,右邊從5起找小於5的數字,找到1,但此時由於6在1的右面,,即右指針<左指針,左右指針交叉,此時划分結束。原數列被划分為兩部分,左側子數列只有一個元素,即為1,其為小於閾值的子數列;右側子數列包括5個元素,均為大於閾值5的元素。

(3)代碼實現:

package com.test.insertsort;

/**
 * 划分、遞歸、快排
 * @author bjh
 *
 */
public class QuickSort {
    
    /**待排序、划分數組*/
    private int[] array;
    /**數組長度*/
    private int length;
    
    public QuickSort(int[] array){
        this.array = array;
        this.length = array.length;
    }
    
    /**
     * 打印元素
     */
    public void printArray(){
        for(int i=0; i<length; i++){
            System.out.print(array[i]+" ");
        }
        System.out.println();
    }
    
    
    /**
     * 划分
     * @return 划分的分界點
     */
    public int partition(int left, int right, int pivot){
        //左指針的起點,left-1是由於在后面的循環中,每循環一次左指針都要右移,
        //這樣可以確保左指針從左邊第一個元素開始,不然是從第二個開始
        int leftpoint = left-1;
        //右指針的起點,right+1是由於后面的循環中,每循環一次右指針都要左移,
        //這樣可以確保右指針從最右邊開始,不然是從倒數第二個開始
        int rightpoint = right+1;
        while(true){
            //找到左邊大於pivot的數據,或者走到了最右邊仍然沒有找到比pivot大的數據
            while(leftpoint<right && array[++leftpoint]<pivot);
            //找到右邊小於pivot的數據,或者走到了最左邊仍然沒有找到比pivot小的數據
            while(rightpoint>left && array[--rightpoint]>pivot);
            //左指針和右指針重疊或相交
            if(leftpoint >= rightpoint){
                break;
            }else{
                //交換左邊大的和右邊小的數據
                swap(leftpoint,rightpoint);
            }
        }
        //返回分界點,即右邊子數組中最左邊的點
        return leftpoint;
    }
    
    
    /**
     * 交換數據
     */
    public void swap(int leftpoint,int rightpoint){
        int temp = array[leftpoint];
        array[leftpoint] = array[rightpoint];
        array[rightpoint] = temp;
    }
    
    public static void main(String args[]){
        int[] array = {99,78,26,17,82,36,9,81,22,100,30,20,17,85};
        QuickSort qs = new QuickSort(array);
        System.out.println("划分前的數據為:");
        qs.printArray();
        int bound = qs.partition(0, array.length-1, 50);
        System.out.println("划分后的數據為:");
        qs.printArray();
        System.out.println("划分的分界點為:" + array[bound] + ",分界點的坐標為:" + bound);
    }

}

運行結果為:

持續更新中。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM