Java中快速排序優(yōu)化技巧之隨機取樣、三數(shù)取中和插入排序
前言
快速排序(Quick Sort)是一種高效的排序算法,它的平均時間復雜度為O(n log n)。然而,在某些情況下,快速排序可能表現(xiàn)不佳,特別是在輸入數(shù)據(jù)近乎有序或包含大量重復元素時。為了解決這些問題,我們可以對快速排序進行一些優(yōu)化。本文將介紹Java語言中如何使用隨機取樣、三數(shù)取中和插入排序等優(yōu)化技巧來提高快速排序的性能。
快速排序基礎
快速排序的基本思想是選擇一個基準元素(pivot),將數(shù)組分成兩個子數(shù)組,小于基準的元素放在左邊,大于基準的元素放在右邊,然后對這兩個子數(shù)組遞歸地進行排序。
public static void quickSort(int[] arr){
quick(arr,0,arr.length-1);
}
private static void quick(int[] arr,int start,int end){
if (start>=end){
return;
}
int pivot=partition(arr,start,end);
quick(arr,start,pivot-1);
quick(arr,pivot+1,end);
}
private static int partition(int[] arr,int left,int right ){
int tmp=arr[left];
while (left<right){
while (left<right&&arr[right]>=tmp){
right--;
}
arr[left]=arr[right];
while (left<right&&arr[left]<=tmp){
left++;
}
arr[right]=arr[left];
}
arr[left]=tmp;
return left;
}優(yōu)化1:隨機取樣
在快速排序中,如果每次選擇的基準元素都是數(shù)組的最左邊或最右邊,那么在輸入數(shù)據(jù)接近有序時,性能會下降。為了解決這個問題,我們可以隨機選擇基準元素。
private static void quick(int[] arr,int start,int end){
if (start>=end){
return;
}
int randomIndex = getRandomIndex(start, end);
swap(arr, start, randomIndex);
int pivot=partition(arr,start,end);
quick(arr,start,pivot-1);
quick(arr,pivot+1,end);
}
public int getRandomIndex(int low, int high) {
Random rand = new Random();
return rand.nextInt(high - low + 1) + low;
}隨機選擇基準元素可以減小快速排序在特定輸入下的性能波動。
優(yōu)化2:三數(shù)取中
另一個性能優(yōu)化的方法是選擇中位數(shù)作為基準元素。這可以避免最壞情況下的快速排序性能下降。
private static void quick(int[] arr,int start,int end){
if (start>=end){
return;
}
//三數(shù)取中法
int index=midThree(arr,start,end);
int tmp=arr[start];
arr[start]=arr[index];
arr[index]=tmp;
int pivot=partition1(arr,start,end);
quick(arr,start,pivot-1);
quick(arr,pivot+1,end);
}
private static int midThree(int[] arr,int left,int right){
int mid=(left+right)/2;
if (arr[left]<right){
if (arr[mid]<arr[left]){
return left;
}else if (arr[mid]>arr[right]){
return right;
}else {
return mid;
}
}else {
//arr[left]>right
if (arr[mid]<arr[right]){
return right;
}else if (arr[mid]>arr[left]){
return left;
}else {
return mid;
}
}
}三數(shù)取中的方法可以有效地避免快速排序的最壞情況,提高了算法的穩(wěn)定性。
優(yōu)化3:插入排序
對于小規(guī)模的數(shù)組,快速排序的遞歸開銷可能會變得顯著。在這種情況下,使用插入排序可以提高性能。
private static void quick(int[] arr,int start,int end){
if (start>=end){
return;
}
if(end-start+1<=14){
//插入排序
insertSort2(arr, start, end);
return;
}
//三數(shù)取中法
int index=midThree(arr,start,end);
int tmp=arr[start];
arr[start]=arr[index];
arr[index]=tmp;
int pivot=partition(arr,start,end);
quick(arr,start,pivot-1);
quick(arr,pivot+1,end);
}
public static void insertSort2(int[] arr,int start,int end){
for (int i = start; i <= end; i++) {
int temp=arr[i];
int j=i-1;
while (j>=0&&arr[j]>temp){
arr[j+1]=arr[j];
j--;
}
arr[j+1]=temp;
}
}
private static int midThree(int[] arr,int left,int right){
int mid=(left+right)/2;
if (arr[left]<right){
if (arr[mid]<arr[left]){
return left;
}else if (arr[mid]>arr[right]){
return right;
}else {
return mid;
}
}else {
//arr[left]>right
if (arr[mid]<arr[right]){
return right;
}else if (arr[mid]>arr[left]){
return left;
}else {
return mid;
}
}
}
private static int partition(int[] arr,int left,int right ){
int tmp=arr[left];
while (left<right){
while (left<right&&arr[right]>=tmp){
right--;
}
arr[left]=arr[right];
while (left<right&&arr[left]<=tmp){
left++;
}
arr[right]=arr[left];
}
arr[left]=tmp;
return left;
}注意:代碼里的小于14長度是我自己規(guī)定的,各位友友可以自己定義小數(shù)組的長度~~
插入排序在小規(guī)模數(shù)組上的性能通常比快速排序更好~~

總結:
在Java中,優(yōu)化快速排序的方法包括隨機取樣、三數(shù)取中和插入排序。這些優(yōu)化可以改善快速排序在各種輸入情況下的性能表現(xiàn),使其成為一種強大而高效的排序算法。通過合理地選擇這些優(yōu)化技巧,可以根據(jù)實際需求來提高算法的性能。喜歡的友友可以關注一下博主噢??
到此這篇關于Java中快速排序優(yōu)化技巧之隨機取樣、三數(shù)取中和插入排序的文章就介紹到這了,更多相關Java隨機取樣、三數(shù)取中和插入排序內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
IDEA 中創(chuàng)建Spring Data Jpa 項目的示例代碼
這篇文章主要介紹了IDEA 中創(chuàng)建Spring Data Jpa 項目的示例代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
關于@OnetoMany關系映射的排序問題,使用注解@OrderBy
這篇文章主要介紹了關于@OnetoMany關系映射的排序問題,使用注解@OrderBy,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
使用原生JDBC動態(tài)解析并獲取表格列名和數(shù)據(jù)的方法
這篇文章主要介紹了使用原生JDBC動態(tài)解析并獲取表格列名和數(shù)據(jù),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08
Springboot+Shiro記錄用戶登錄信息并獲取當前登錄用戶信息的實現(xiàn)代碼
這篇文章主要介紹了Springboot+Shiro記錄用戶登錄信息,并獲取當前登錄用戶信息,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
配置java環(huán)境變量(linux mac windows7)
本文給大家詳細總結介紹了Linux、MAC以及Windows下配置java環(huán)境變量的方法,非常的細致全面,有需要的小伙伴可以參考下2015-11-11
Java?properties?和?yml?的區(qū)別解析
properties和yml都是Spring?Boot支持的兩種配置文件,它們可以看做Spring?Boot在不同時期的兩種“產品”,這篇文章主要介紹了Java?properties?和?yml?的區(qū)別,需要的朋友可以參考下2023-02-02
springboot+vue+elementsUI實現(xiàn)分角色注冊登錄界面功能
這篇文章主要給大家介紹了關于springboot+vue+elementsUI實現(xiàn)分角色注冊登錄界面功能的相關資料,Spring?Boot和Vue.js是兩個非常流行的開源框架,可以用來構建Web應用程序,需要的朋友可以參考下2023-07-07

