1. 程式人生 > 實用技巧 >Java實現的幾大排序

Java實現的幾大排序

排序

筆者依次寫了幾大排序,只是幾個比較基礎的基本版本,不是優化後的排序演算法,日後筆者有空在一一完善,具體理論未涉及

氣泡排序1

選擇排序1

插入排序1

希爾排序1

快速排序1

歸併排序1

堆排序1




import java.util.Scanner;

public class demoSort {
private static int array[]; //輸入資料用陣列表示
private static int val; //switch-case判斷條件

//氣泡排序
public static void BubbleSort(int arr[]) {
for (int i = 0; i < arr.length - 1; i++) { //外層迴圈控制排序趟數
for (int j = 0; j < arr.length - 1 - i; j++) { //內層迴圈控制每一趟排序多少次
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("氣泡排序完成後的數為");
for (int num : arr) {
System.out.print(num + " ");
}

}

//快速排序,利用java多型的特性,僅僅方便輸出哦,程式碼優化而已
public static void quickSort(int arr[]) {
quickSort(arr, 0, arr.length - 1);
System.out.println("快速排序完成後的數為");
for (int num : arr) {
System.out.print(num + " ");
}
}

//https://www.cnblogs.com/MOBIN/p/4681369.html
public static void quickSort(int arr[], int left, int right) {
int temp = 0;
if (left <= right) { //待排序的元素至少有兩個的情況
temp = arr[left]; //待排序的第一個元素作為基準元素
while (left != right) { //從左右兩邊交替掃描,直到left = right

while (right > left && arr[right] >= temp)
right--; //從右往左掃描,找到第一個比基準元素小的元素
arr[left] = arr[right]; //找到這種元素arr[right]後與arr[left]交換

while (left < right && arr[left] <= temp)
left++; //從左往右掃描,找到第一個比基準元素大的元素
arr[right] = arr[left]; //找到這種元素arr[left]後,與arr[right]交換

}
arr[right] = temp; //基準元素歸位
quickSort(arr, left, left - 1); //對基準元素左邊的元素進行遞迴排序
quickSort(arr, right + 1, right); //對基準元素右邊的進行遞迴排序
}

}

// 選擇排序
public static void selectSort(int arr[]) {
for (int i = 0; i < arr.length; i++) {
int index = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[index])
index = j;

}
if (index == i)
continue;
else {
int temp;
temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
}
}
System.out.println("選擇排序完成後的數為");
for (int num : arr) {
System.out.print(num + " ");
}
}

// 插入排序
public static void insertSort(int arr[]) {
for (int i = 1; i < arr.length; i++) {
int j;
if (arr[i] < arr[i - 1]) {
int temp = arr[i];
for (j = i - 1; j >= 0 && temp < arr[j]; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = temp;
}
}
System.out.println("插入排序完成後的數為");
for (int num : arr) {
System.out.print(num + " ");
}
}

// 希爾排序
public static void shellSort(int arr[]) {
int increasement = arr.length;
int i, j, k;
do {
// 確定分組的增量
increasement = increasement / 3 + 1;
for (i = 0; i < increasement; i++) {
for (j = i + increasement; j < arr.length; j += increasement) {
if (arr[j] < arr[j - increasement]) {
int temp = arr[j];
for (k = j - increasement; k >= 0 && temp < arr[k]; k -= increasement) {
arr[k + increasement] = arr[k];
}
arr[k + increasement] = temp;
}
}
}
} while (increasement > 1);
System.out.println("希爾排序完成後的數為");
for (int num : arr) {
System.out.print(num + " ");
}
}

//歸併排序,注意由於Java多型好用,作者在這想玩一玩多型特性,作為學習者。簡而言之,就是在無限套娃
public static void mergeSort(int arr[]) {
mergeSort(arr, 0, arr.length - 1);
System.out.println("歸併排序完成後的數為");
for (int num : arr) {
System.out.print(num + " ");
}
}

private static void mergeSort(int a[], int p, int r) {
if (p < r) {
int q = (p + r) / 2;//p表示從子序列的哪個索引開始,q表示子序列中間的位置
mergeSort(a, p, q);
mergeSort(a, q + 1, r);
mergeSort(a, p, q, r);
}
}

private static void mergeSort(int a[], int p, int q, int r) {
// n1和n2分別表示左邊序列和右邊序列的長度。左邊從p開始包括q,右邊從q+1開始
int n1 = q - p + 1;
int n2 = r - q;
int L[] = new int[n1];
int R[] = new int[n2];
// k用來表示當前遍歷的陣列a的索引
int i = 0, j = 0, k = 0;
// 分別給L和R賦值
for (i = 0, k = p; i < n1; i++, k++) {
L[i] = a[k];
}
// 從右邊開始
for (j = 0, k = q + 1; j < n2; j++, k++) {
R[j] = a[k];
}
// 比較大小,從小到大排列
for (i = 0, j = 0, k = p; i < n1 && j < n2; k++) {
if (L[i] > R[j]) {
a[k] = R[j];
j++;
} else {
a[k] = L[i];
i++;
}
}//for
// 將兩個陣列中剩下的數放到a中
if (i < n1) {
for (j = i; j < n1; j++, k++) {
a[k] = L[j];
}
}
if (j < n2) {
for (i = j; i < n2; i++, k++) {
a[k] = R[i];
}
}
}

//堆排序
public static void heapSort(int arr[]) {
if (arr == null || arr.length == 0) {
return;
}
int len = arr.length;
// 構建大頂堆,這裡其實就是把待排序序列,變成一個大頂堆結構的陣列
buildMaxHeap(arr);

// 交換堆頂和當前末尾的節點,重置大頂堆
for (int i = len - 1; i > 0; i--) {
swap(arr, 0, i);
len--;
heapInit(arr, 0, len);
}
System.out.println("堆排序完成後的數為");
for (int num : arr) {
System.out.print(num + " ");
}
}

private static void buildMaxHeap(int arr[]) {
// 從最後一個非葉節點開始向前遍歷,調整節點性質,使之成為大頂堆
for (int i = (int) Math.floor(arr.length / 2) - 1; i >= 0; i--) {
heapInit(arr, i, arr.length);
}
}

private static void heapInit(int arr[], int i, int len) {
// 先根據堆性質,找出它左右節點的索引
int left = 2 * i + 1;
int right = 2 * i + 2;
// 預設當前節點(父節點)是最大值。
int largestIndex = i;
if (left < len && arr[left] > arr[largestIndex]) {
// 如果有左節點,並且左節點的值更大,更新最大值的索引
largestIndex = left;
}
if (right < len && arr[right] > arr[largestIndex]) {
// 如果有右節點,並且右節點的值更大,更新最大值的索引
largestIndex = right;
}

if (largestIndex != i) {
// 如果最大值不是當前非葉子節點的值,那麼就把當前節點和最大值的子節點值互換
swap(arr, i, largestIndex);
// 因為互換之後,子節點的值變了,如果該子節點也有自己的子節點,仍需要再次調整。
heapInit(arr, largestIndex, len);
}
}

private static void swap(int arr[], int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

//輸入模組
public static void Scanner() {
Scanner scanner = new Scanner(System.in);
System.out.println();
System.out.println("輸入你要求多少個數的排序");
int n = scanner.nextInt();
array = new int[n];
System.out.println("輸入你要排序的" + n + "個數,並且按照空格鍵隔開");
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
}

public static void main(String[] args) {
while (true) {
/*說明這個一個排序說明,有點無線套娃,仔細檢視哦*/
/*BubbleSort(array); //氣泡排序
quickSort(array); //快速排序
selectSort(array); //選擇排序
insertSort(array); //插入排序
shellSort(array); //希爾排序
mergeSort(array); //歸併排序
/heapSort(array); //堆排序*/
Scanner();
System.out.println("----------輸入你要選擇的排序----------------");
System.out.println("----------1氣泡排序--2快速排序--------------");
System.out.println("----------3選擇排序--4插入排序--------------");
System.out.println("----------5希爾排序--6歸併排序--------------");
System.out.println("----------7堆排序-------------------------");
Scanner scanner = new Scanner(System.in);
val = scanner.nextInt();
switch (val) {
case 1:
BubbleSort(array); //氣泡排序
break;
case 2:
quickSort(array); //快速排序
break;
case 3:
selectSort(array); //選擇排序
break;
case 4:
insertSort(array);//插入排序
break;
case 5:
shellSort(array); //希爾排序
break;
case 6:
mergeSort(array); //歸併排序
break;
case 7:
heapSort(array); //堆排序
break;
default:
System.out.println("該輸入不存在, 請重新輸入\n");
}
//湊個300行玩玩
//湊個300行玩玩
}
}
}