【Java資料結構與演算法】第八章 快速排序、歸併排序和基數排序
第八章 快速排序、歸併排序和基數排序
文章目錄
第八章 快速排序、歸併排序和基數排序
一、快速排序
1.基本介紹
2.程式碼實現
二、歸併排序
1.基本介紹
2.程式碼實現
三、基數排序
1.基本介紹
2.程式碼實現
一、快速排序
1.基本介紹
快速排序(Quick Sort)是在氣泡排序基礎上的遞迴分治法,其基本原理:選擇一個關鍵值作為基準值。比基準值小的都在左邊序列, 比基準值大的都在右邊
當一個等於基準元素的元素在基準元素的右邊時,由於小於等於基準元素的元素都要移動到基準元素左邊,所以該元素和基準元素的相對位置就改變了,因此快速排序是一種不穩定的排序演算法
演算法步驟
從數列中挑出一個元素,稱為 “基準”(pivot)
重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割槽退出之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作
遞迴地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序
2.程式碼實現
package com.sisyphus.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class QuickSort {
public static void main(String[] args) {
//int[] arr = {-9, 78, 0, 23, -567, 70, -1, 900, 4561};
//quickSort(arr,0,arr.length -1);
(Arrays.toString(arr));
//建立一個 80000 個隨機數的陣列
int[] arr = new int[80000];
for (int i = 0; i
}
public static void quickSort(int[] arr,int left, int right){
int l =left;
int r = right;
int pivot = arr[(left + right) / 2];
int temp = 0;//用於交換
//while 迴圈的目的是讓比 pivot 小的值放到左邊,比 pivot 大的值放到右邊
while(l //在 pivot 左邊一直找,找到一個大於等於 pivot 的值才退出
while (arr[l] l += 1;
}
//在 pivot 右邊一直找,找到一個小於等於 pivot 的值才退出
while(arr[r] > pivot){
r -= 1;
}
//如果 l >= r 說明 pivot 左右兩邊的值已經按照左邊全是小於等於 pivot,右邊全是大於等於 pivot 的規定排列好了
if(l >= r){
break;
}
//交換
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//如果交換完後,發現 arr[l] == pivot
if (arr[l] == pivot){
r -= 1;
}
//如果交換完後,發現 arr[r] == pivot
if (arr[r] == pivot){
l += 1;
}
}
//如果 l == r,必須 l++,r–,否則會出現棧溢位
if (l == r){
l++;
r–;
}
//向左遞迴
if (left quickSort(arr,left,r);
}
//向右遞迴
if (right > l){
quickSort(arr,l,right);
}
}
}
二、歸併排序
1.基本介紹
歸併排序(Merge sort)是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序
在交換過程中,2 個元素如果大小相等也沒有任何操作交換,這不會破壞穩定性。合併過程中我們可以令相同的元素本來在前的還保持在前,這樣就保證了相對順序沒有改變,因此歸併排序也是穩定的排序演算法
演算法步驟
申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列
設定兩個指標,最初位置分別為兩個已經排序序列的起始位置
比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置
重複步驟 3 直到某一指標達到序列尾
將另一序列剩下的所有元素直接複製到合併序列尾
2.程式碼實現
package com.sisyphus.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class MergeSort {
public static void main(String[] args) {
//int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
(“歸併排序後” + Arrays.toString(arr));
//建立一個 80000 個隨機數的陣列
int[] arr = new int[80000];
for (int i = 0; i
}
//分 + 合的方法
public static void mergeSort(int[] arr, int left, int right, int[] temp){
if (left int mid = (left + right) / 2;//中間索引
//向左遞迴進行分解
mergeSort(arr, left, mid, temp);
//向右遞迴進行分解
mergeSort(arr, mid+1,right,temp);
//合併
merge(arr, left, mid, right, temp);
}
}
//合併的方法
public static void merge(int[] arr, int left, int mid, int right, int[] temp){
int i = left; //初始化 i,左端有序序列的初始索引
int j = mid + 1;//初始化 j,右端有序序列的初始索引
int t = 0; //指向 temp 陣列的當前索引
//(一)
//先把左右兩邊(有序)的資料按照規則填充到 temp 陣列
//直到左右兩邊的有序序列有一邊處理完畢
while((i //如果左邊的有序序列的當前元素小於等於右邊有序序列的當前元素
//將左邊的當前元素複製到 temp 陣列
//然後 t 後移,i 後移
if (arr[i] temp[t] = arr[i];
t++;
i++;
}else{//反之,將右邊的當前元素複製到 temp 陣列
temp[t] = arr[j];
t++;
j++;
}
}
//(二)
//有剩餘資料的一邊,把其中的資料依次全部填充到 temp
while(i temp[t] = arr[i];
t++;
i++;
}
while(j temp[t] = arr[j];
t++;
j++;
}
//(三)
//將 temp 陣列的元素複製到 arr
//注意:並不是每次都複製所有資料
t = 0;
int tempLeft = left;//
//第一次合併時 tempLeft = 0,right = 1 第二次合併時 tempLeft = 2,right = 3 第三次合併時 tempLeft = 0,right = 3
//最後一次 tempLeft = 0,right = 7
(“tempLeft=”+tempLeft+" right="+right);
while(tempLeft arr[tempLeft] = temp[t];
t++;
tempLeft++;
}
}
}
三、基數排序
1.基本介紹
基數排序(Radix Sort)是一種非比較型整數排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。由於整數也可以表達字串(比如名字或日期)和特定格式的浮點數,所以基數排序也不是隻能使用於整數
基數排序基於分別排序,分別收集,因此是穩定的排序演算法
演算法步驟
將所有待比較數值(正整數)統一為同樣的數位長度,數位較短的數前面補零
從最低位開始,依次進行一次排序
從最低位排序一直到最高位排序完成以後, 數列就變成一個有序序列
計數排序、桶排序和基數排序都利用了桶的概念,但對桶的使用方法上有明顯差異:
桶排序:每個桶儲存一定範圍的數值
計數排序:每個桶只儲存單一鍵值
基數排序:根據鍵值的每位數字來分配桶
2.程式碼實現
package com.sisyphus.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class RadixSort {
public static void main(String[] args) {
//int[] arr = {53, 3, 542, 748, 14, 214};
//建立一個 80000 個隨機數的陣列
int[] arr = new int[80000];
for (int i = 0; i
}
public static void radixSort(int[] arr){
//1.得到陣列中最大的位數
int max = arr[0];//假設第一個數就是最大數
for (int i = 1; i max){
max = arr[i];
}
}
//得到最大數是幾位數
int maxLength = (max + "").length();
//定義一個二維陣列,表示 10 個桶,每個桶就是一個一維陣列
//說明
//1.二維陣列包含 10 個一維陣列
//2.為了防止在放入資料的時候溢位,設定每個一維陣列的大小為 arr.length
//3.由此可見,基數排序是一種以空間換時間的演算法
int[][] bucket = new int[10][arr.length];
//為了記錄每個桶中,實際存放了多少個資料,我們定義一個一維陣列來記錄各個桶的每次放入的資料個數
//可以這樣理解
//比如:bucketElementCounts[0],記錄的就是 bucket[0] 桶的放入資料的個數
int[] bucketElementCounts = new int[10];
for (int i = 0, n = 1; i
}
}
————————————————
版權宣告:本文為CSDN博主「313YPHU3」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/qq_45593575/article/details/118880356
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1795/viewspace-2797037/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料結構與演算法——排序演算法-歸併排序資料結構演算法排序
- 歸併排序和基數排序排序
- 【資料結構與演算法】歸併排序資料結構演算法排序
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序
- 演算法與資料結構高階排序演算法之歸併排序演算法資料結構排序
- 快速排序&&歸併排序排序
- 資料結構與演算法——排序演算法-基數排序資料結構演算法排序
- 【資料結構與演算法】高階排序(希爾排序、歸併排序、快速排序)完整思路,並用程式碼封裝排序函式資料結構演算法排序封裝函式
- 氣泡排序、歸併排序與快速排序比較排序
- 四、歸併排序 && 快速排序排序
- php插入排序,快速排序,歸併排序,堆排序PHP排序
- 演算法之常見排序演算法-氣泡排序、歸併排序、快速排序演算法排序
- 演算法:排序連結串列:歸併排序演算法排序
- 排序演算法__歸併排序排序演算法
- 排序演算法:歸併排序排序演算法
- 排序演算法 - 歸併排序排序演算法
- 排序演算法(歸併排序)排序演算法
- 歸併排序--排序演算法排序演算法
- 演算法與資料結構系列 ( 七 ) - 歸併排序- Merge Sort演算法資料結構排序
- Python八大演算法的實現,插入排序、希爾排序、氣泡排序、快速排序、直接選擇排序、堆排序、歸併排序、基數排序。Python演算法排序
- php實現 歸併排序,快速排序PHP排序
- (建議收藏)2020最新排序演算法總結:冒泡、選擇、插入、希爾、快速、歸併、堆排序、基數排序排序演算法
- 資料結構:歸併排序(非遞迴)資料結構排序遞迴
- 排序演算法之 '歸併排序'排序演算法
- 資料結構與演算法之快速排序資料結構演算法排序
- (戀上資料結構筆記):計數排序、基數排序 、桶排序資料結構筆記排序
- 資料結構和演算法(Golang實現)(25)排序演算法-快速排序資料結構演算法Golang排序
- 從零開始學資料結構和演算法 (五) 分治法 (二分查詢、快速排序、歸併排序)資料結構演算法排序
- java歸併排序Java排序
- 歸併排序與快速排序的一個實現與理解排序
- Java資料結構與排序演算法 (三)Java資料結構排序演算法
- Java資料結構與排序演算法 (一)Java資料結構排序演算法
- Java資料結構與排序演算法 (二)Java資料結構排序演算法
- 排序演算法之歸併,快速,堆和桶排序演算法
- python演算法與資料結構-快速排序(36)Python演算法資料結構排序
- 資料結構與演算法 基礎排序資料結構演算法排序
- 資料結構和演算法面試題系列—排序演算法之快速排序資料結構演算法面試題排序
- 資料結構與演算法——排序演算法-氣泡排序資料結構演算法排序