插入排序、選擇排序、歸並排序、堆排序、快速排序的JAVA實現


靜下心來,重拾初衷

那么就從最基本的開始吧


package com.thedman.test;


public class Test {

public static void main(String[] args) {
int[] input = new int[]{24, 55, 12, 0, 78, 15, 99, 88, 100, 25};

//insertionSort(input);
//selectionSort(input);
//mergeSort(input);
//heapSort(input);
quickSort(input, 0, input.length - 1);

for (int i : input) {
System.out.print(i + ", ");
}
}

/**
* 交換數組中倆數據位置
* @param data
* @param i
* @param j
*/
private static void swap(int[] data, int i, int j) {
if (i == j) {
return;
}
data[i] = data[i] + data[j];
data[j] = data[i] - data[j];
data[i] = data[i] - data[j];
}

/**
* 插入排序
* 最壞復雜度為O(n^2)
* @param input
*/
public static void insertionSort(int[] input) {
int length = input.length;
for (int i = 0; i < length; i++) {
int j = i;
while (j > 0 && input[j] < input[j - 1]) {
swap(input, j, j-1);
j -- ;
}
}
}

/**
* 選擇排序
* 最壞復雜度為O(n^2)
* @param input
*/
public static void selectionSort(int[] input) {
for (int i = 0; i < input.length; i++) {
int min = i;
for (int j = i + 1; j < input.length; j++) {
if (input[min] > input[j]) {
min = j;
}
}
if (i != min) {
swap(input, min, i);
}
}
}

/**
* 歸並排序
* 最壞復雜度為O(nlogn)
* @param input
*/
public static void mergeSort(int[] input) {
sort(input, 0, input.length - 1);
}

private static void sort(int[] data, int left, int right) {
if (left >= right)
return;

int center = (left + right) / 2;
sort(data, left, center);
sort(data, center + 1, right);
merge(data, left, center, right);

}

private static void merge(int[] data, int left, int center, int right) {
// 臨時數組
int[] tmpArr = new int[data.length];
// 右數組第一個元素索引
int mid = center + 1;
// third 記錄臨時數組的索引
int third = left;
// 緩存左數組第一個元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 從兩個數組中取出最小的放入臨時數組
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入臨時數組(實際上兩個while只會執行其中一個)
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
// 將臨時數組中的內容拷貝回原數組中
// (原left-right范圍的內容被復制回原數組)
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}

/**
* 堆排序
* 復雜度O(nlogn)
* @param input
*/
public static void heapSort(int[] input) {
for (int i = 0; i < input.length; i++) {
createMaxdHeap(input, input.length - 1 - i);
swap(input, 0, input.length - 1 - i);
}
}

private static void createMaxdHeap(int[] data, int lastIndex) {
for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
// 保存當前正在判斷的節點
int k = i;
// 若當前節點的子節點存在
while (2 * k + 1 <= lastIndex) {
// biggerIndex總是記錄較大節點的值,先賦值為當前判斷節點的左子節點
int biggerIndex = 2 * k + 1;
if (biggerIndex < lastIndex) {
// 若右子節點存在,否則此時biggerIndex應該等於 lastIndex
if (data[biggerIndex] < data[biggerIndex + 1]) {
// 若右子節點值比左子節點值大,則biggerIndex記錄的是右子節點的值
biggerIndex++;
}
}
if (data[k] < data[biggerIndex]) {
// 若當前節點值比子節點最大值小,則交換2者得值,交換后將biggerIndex值賦值給k
swap(data, k, biggerIndex);
k = biggerIndex;
} else {
break;
}
}
}
}

/**
* 快速排序
* 復雜度O(n^2)
* @param input
* @param start
* @param end
*/
public static void quickSort(int[] input, int start, int end) {
if (start >= end)
return;
//以起始索引為分界點
int pivot = input[start];
int i = start + 1;
int j = end;
while (true) {
while (i <= end && input[i] < pivot) {
i++;
}
while (j > start && input[j] > pivot) {
j--;
}
if (i < j) {
swap(input, i, j);
} else {
break;
}
}
//交換 j和分界點的值
swap(input, start, j);
//遞歸左子序列
quickSort(input, start, j - 1);
//遞歸右子序列
quickSort(input, j + 1, end);
}

}

以上,堆排序的原理還是不太懂,歸並、堆、快速排序的實現如果讓自己筆試的時候寫,可能還寫不出


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com