Java排序算法分析與實現:快排、冒泡排序、選擇排序、插入排序、歸並排序(二)
阿新 • • 發佈:2018-01-25
第一個元素 spa insert 循環 冒泡排序 author 高級算法 ins -s
一、概述:
上篇博客介紹了常見簡單算法:冒泡排序、選擇排序和插入排序。本文介紹高級排序算法:快速排序和歸並排序。在開始介紹算法之前,首先介紹高級算法所需要的基礎知識:劃分、遞歸,並順帶介紹二分查找算法。
二、劃分:
劃分是快速排序的前提,即把數據分為兩組,大於特定值的數據在一組,小於特定值的數據在另一組。快速排序即是由劃分和遞歸操作來完成的。
(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); } }
運行結果為:
持續更新中。。。。
Java排序算法分析與實現:快排、冒泡排序、選擇排序、插入排序、歸並排序(二)