排序算法小结_学习记录
package p38;
/**
* 排序和查找算法总结
* @author Guozhu Zhu
* @date 2018/9/11
* @version 1.0
*
*/
public class Test06 {
/* ========== Test ========== */
public static void main(String[] args) {
int[] arr = {1, 4, 3, 2, 6, 5, 9, 0};
Sort07(arr);
for (int i : arr) {
System.out.println(i);
}
}
//1. 冒泡排序算法实现, O(n)=n^2; 空间O(n)=1, 稳定的排序算法
public static void Sort(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j+1] < arr[j]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
//2. 直接选择排序算法实现, O(n)=n^2, 空间O(n)=1, 不稳定的排序算法实现
public static void Sort01(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
//3. 直接插入排序算法实现, O(n)=n^2; 空间O(n)=1, 稳定的排序算法实现
public static void Sort02(int[] arr) {
for (int i = 1; i < arr.length; 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;
}
}
//4. 二分插入排序算法实现, O(n)=n^2, 空间O(n)=1, 稳定的排序算法实现
public static void Sort03(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int temp = arr[i];
int low = 0;
int high = i-1;
int mid = 0;
while (low <= high) {
mid = (low+high) / 2;
if (arr[mid] > temp) {
high = mid-1;
} else {
low = mid+1;
}
}
for (int j = i-1; j >= low; j--) {
arr[j+1] = arr[j];
}
arr[low] = temp;
}
}
//5. 希尔排序算法实现, O(n)=nlogn ~ n^2, 最优O(n)=n^1.3, 不稳定的排序算法
public static void Sort04(int[] arr) {
int gap = arr.length-1 / 2;
while (gap >= 1) {
for (int i = gap; i < arr.length; i++) {
int temp = arr[i];
int j = i-gap;
while (j >= 0 && arr[j] > temp) {
arr[j+gap] = arr[j];
j = j-gap;
}
arr[j+gap] = temp;
}
gap = gap / 2;
}
}
//6. 快速排序算法实现, O(n)=nlogn, 空间O(n)=logn, 不稳定的排序
public static void Sort05(int[] arr, int left, int right) {
if (left > right) {
return;
}
int i = left;
int j = right;
int key = arr[i];
while (i < j) {
while (i < j && arr[j] > key) {
j--;
}
arr[i] = arr[j];
while (i < j && arr[i] < key) {
i++;
}
arr[j] = arr[i];
}
arr[i] = key;
Sort05(arr, left, i-1);
Sort05(arr, i+1, right);
}
//6. 归并排序算法实现, O(n)=nlogn, 稳定的排序算法实现
public static void Sort06(int[] arr) {
int[] temp = new int[arr.length];
MergeSort(arr, 0, arr.length, temp);
}
public static void MergeSort(int[] arr, int first, int last, int[] temp) {
if (first < last) {
int mid = (first+last) / 2;
MergeSort(arr, first, mid, temp);
MergeSort(arr, mid+1, last, temp);
Merge(arr, first, mid, last, temp);
}
}
public static void Merge(int[] arr, int first, int mid, int last, int[] temp) {
int i = first;
int j = mid+1;
int m = mid;
int n = last;
int k = 0;
while (i <= m && j <= n) {
if (arr[i] < arr[j]) {
temp[k++] = arr[i];
} else {
temp[k++] = arr[j];
}
}
while (i <= m) {
temp[k++] = arr[i];
}
while (j <= n) {
temp[k++] = arr[j];
}
for (int a = 0; a <= k; a++) {
arr[a+first] = temp[a];
}
}
//7. 堆排序算法实现, O(n)=nlogn, 空间O(n)=1, 不稳定的排序
public static void Sort07(int[] arr) {
//构建大顶堆
int len = arr.length;
for (int i = (int) Math.floor(len/2); i >= 0; i--) {
//下沉调整
downAdjust(arr, i, arr.length-1);
}
//下沉调整堆的结构
for (int i = arr.length-1; i > 0; i--) {
swap(arr, 0, i);
downAdjust(arr, 0, i-1);
}
}
public static void downAdjust(int[] arr, int parentIndex, int length) {
int temp = arr[parentIndex];
int childIndex = parentIndex*2+1;
while (childIndex <= length) {
if (childIndex+1 <= length && arr[childIndex+1] > arr[childIndex]) {
childIndex++;
}
if (temp > arr[childIndex]) {
break;
}
arr[parentIndex] = arr[childIndex];
parentIndex = childIndex;
childIndex = childIndex*2;
}
arr[parentIndex] = temp;
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
补充01:计数排序算法实现
package p1;
/**
* 计数排序算法实现
* @author Guozhu Zhu
* @date 2019/5/31
* @version 1.0
*
*/
public class CountSort02 {
public static void main(String[] args) {
int[] arr = {1, 2, 5, 4, 3, 2, 7, 9, 8, 0, 6};
int[] res = sort(arr);
for (int i : res) {
System.out.println(i);
}
}
//计数排序, 时间复杂度:O(n+k), 空间复杂度:O(n+k), 其中n为要排序的数的个数,k为要排序数组的最大值,稳定的排序
public static int[] sort(int[] arr) {
int k = 100;
int[] count = new int[k+1];
int[] res = new int[arr.length];
//1. 计数
for (int i = 0; i < arr.length; i++) {
count[arr[i]]++;
}
//2. 计算位置
for (int i = 1; i <= k; i++) {
count[i] = count[i] + count[i-1];
}
for (int i = arr.length-1; i >= 0; i--) {
res[count[arr[i]]-1] = arr[i];
count[arr[i]]--;
}
return res;
}
}
补充02:基数排序算法实现
package p1;
/**
* 基数排序算法实现
* @author Guozhu Zhu
* @date 2019/5/31
* @version 1.0
*
*/
public class RadixSort {
public static void main(String[] args) {
int[] arr = {1, 2, 5, 4, 3, 2, 7, 9, 8, 0, 6, 11};
sort(arr);
for (int i : arr) {
System.out.println(i);
}
}
public static int getMax(int a[], int n) {
int max = a[0];
for (int i = 1; i < n; i++) {
if (a[i] > max) {
max = a[i];
}
}
return max;
}
public static void countSort(int a[], int n, int exp) {
int output[] = new int[n];
int i;
int buckets[] = new int[n+1];
//1. 将数据出现的次数存储在buckets[]中
for (i = 0; i < n; i++) {
buckets[(a[i]/exp)%10]++;
}
//2. 更改buckets[i]。目的是让更改后的buckets[i]的值,是该数据在output[]中的位置。
for (i = 1; i < 10; i++) {
buckets[i] += buckets[i - 1];
}
//3. 将数据存储到临时数组output[]中
for (i = n - 1; i >= 0; i--) {
output[buckets[(a[i]/exp)%10] - 1] = a[i];
buckets[(a[i]/exp)%10]--;
}
//4. 将排序好的数据赋值给a[]
for (i = 0; i < n; i++) {
a[i] = output[i];
}
}
public static void sort(int a[]) {
int exp; // 指数。当对数组按个位进行排序时,exp=1;按十位进行排序时,exp=10;...
int max = getMax(a, a.length); // 数组a中的最大值
// 从个位开始,对数组a按"指数"进行排序
for (exp = 1; max/exp > 0; exp *= 10) {
countSort(a, a.length, exp);
}
}
}
补充03:桶排序算法实现
package p1;
/**
* 桶排序算法实现
* @author Guozhu Zhu
* @date 2019/5/31
* @version 1.0
*
*/
public class BuketSort01 {
public static void main(String[] args) {
int[] arr = {1, 2, 5, 4, 3, 2, 7, 9, 8, 0, 6, 11};
sort(arr);
for (int i : arr) {
System.out.println(i);
}
}
public static void sort(int[] arr) {
int max = 12;
int i, j;
int buckets[] = new int[max];
// 1. 计数
for(i = 0; i < arr.length; i++) {
buckets[arr[i]]++;
}
// 2. 排序
for (i = 0, j = 0; i < max; i++) {
while ((buckets[i]--) > 0 ) {
arr[j++] = i;
}
}
}
}
补充04:鸡尾酒排序算法实现
/**
* @author Guozhu Zhu
* @date 2019/07/12
* @version 1.0
*/
//也称作双向冒泡排序算法, O(n^2), 在数组有序的情况下,最好O(n)时间复杂度
public static void cockTail(int[] arr) {
int temp = 0;
for (int i = 0; i < arr.length-1/2; i++) {
boolean isSorted = true;
for (int j = i; j < arr.length-1-i; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
isSorted = false;
}
if (isSorted) {
break;
}
for (int j = arr.length-1-i; j > i; j--) {
if (arr[j] < arr[j-1]) {
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
isSorted = false;
}
if (isSorted) {
break;
}
}
}