↵
import com.sun.scenario.effect.Merge;
public class Sort {
private static void swap(int arr[], int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 1. 冒泡排序
// 时间复杂度为 N^2
// 空间复杂度O(1)
// 稳定排序
public static void bubbleSort(int[] arr, int len) {
/**
* 1>相邻两数进行比较,比较一遍后,最后一个数最大。
* 2>进行n-1遍后,排列有序
*/
for (int i = 0; i < len; i++) {
boolean flag = true;
for (int j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) { //相邻两数进行比较,若前大于后,交换俩数
swap(arr, j, j + 1);
flag = false;
}
}
if (flag)
continue;
}
}
/**
* 2. 插入排序:将数据插入前面已经排好序的队列中
* 平均时间复杂度为 N^2
* 空间复杂度O(1)
* 稳定排序
*
* @param arr
* @param length
*/
public static void insertSort(int[] arr, int length) {
int i, j;
for (i = 1; i < length; i++) {
int tmp = arr[i];
for (j = i; j > 0 && arr[j - 1] > tmp; j--) {
arr[j] = arr[j - 1];
}
arr[j] = tmp;
}
}
/**
* 3. 选择排序:
* 每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,
* 直到所有元素排完为止。
*/
public static void selectSort(int[] arr, int len) {
for (int i = 0; i < len; i++) {
int min = i;
for (int j = i + 1; j < len; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
if (min != i)// 若min发生改变,进行交换
swap(arr, i, min);
}
}
/**
* 4. 希尔排序:改进版的插入排序
* 步长由长到短分组,进行排序,直到步长为1为止
*
* @param arr
* @param len
*/
public static void shellSort(int[] arr, int len) {
for (int gap = len / 2; gap > 0; gap /= 2) {// 间隔量gap
// 下面相当于插入排序(插入排序相当于是间隔量为1的希尔排序)
for (int i = gap; i < len; i++) {
int tmp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > tmp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = tmp;
}
}
}
/**
* 5.归并排序: 拆分 合并
* 时间复杂度: O(NlogN)
* 空间复杂度: 对于数组来说, O(N)
* 稳定性: 稳定排序
*
* @param arr
* @param low
* @param high 数组最后一个的下标
*/
public static void mergeSort(int[] arr, int low, int high) {
if (low < high) {
// 1>拆分
int mid = (low + high) / 2;
// 递归解决左右两边子问题
mergeSort(arr, low, mid);
mergeSort(arr, mid + 1, high);
// 2>左右归并
Merge(arr, low, mid, high);
}
}
/**
* <2> 合并
*
* @param arr 数组
* @param low 低下标
* @param mid 中间位置数值下标
* @param high 高下标
*/
public static void Merge(int[] arr, int low, int mid, int high) {
int[] pro = new int[high - low + 1]; // 一个辅助数组
int i = low;
int j = mid + 1;
int index = 0;// 辅助数组索引
// 1>两个数组从0开始比较,并将小的数放入辅助数组中
while (i <= mid && j <= high) {
if (arr[i] < arr[j])
pro[index++] = arr[i++];
else
pro[index++] = arr[j++];
}
// 2>若;两个数组个数不同,比较完1>后,个数少的数组会有余留
while (i <= mid)
pro[index++] = arr[i++];
while (j <= high)
pro[index++] = arr[j++];
// 3>将排序好的辅助数组中的值放入原数组
for (int k = 0; k < index; k++)
arr[k + low] = pro[k];
}
// 6. 堆排序:先建大堆,然后循环删除堆顶元素
public static void heapSort(int[] arr, int size) {
// 创建大堆
createHeap(arr, size);
// 循环删除堆顶
for (int i = 0; i < size; i++) {
heapPop(arr, size - i);
}
}
// 堆删
private static void heapPop(int[] arr, int size) {
if (size <= 1)
return;
swap(arr, 0, size - 1);
adjustDown(arr, size - 1, 0);
}
// 创建最大堆
private static void createHeap(int[] arr, int size) {
if (size <= 1) // 个数为1的话,直接返回
return;
int parent = (size - 1 - 1) / 2; // 从末尾起第一个非叶子结点
for (int i = parent; i >= 0; i--) {
adjustDown(arr, size, i);
}
}
// 向下调整
private static void adjustDown(int[] arr, int size, int i) {
int parent = i;
int child = 2 * parent + 1;
while (child < size) {
// 比较左右孩子结点大小
if (child + 1 < size && arr[child] < arr[child + 1])
child = child + 1;
// 大孩子与父结点进行比较
if (arr[parent] < arr[child])
swap(arr, child, parent);
// 继续向下调整
parent = child; // child相当于一个标记,为与父结点进行交换的孩子的下标
child = 2 * parent + 1;
}
}
// 7. 快速排序
/**
* 时间复杂度: 最坏 O(N ^ 2)(如果数组是逆序的) 平均水平 O(NlogN)
* 不稳定排序
* @param arr
* @param start
* @param end
*/
public static void quickSort(int[] arr, int start, int end) {
int pivot = arr[start];
int left = start;
int right = end;
while (left < right) {
// 先从右边寻找比基准值小的数
while (left < right && arr[right] > pivot)
right--;
// 左边开始寻找比基准值大的数
while (left < right && arr[left] < pivot)
left++;
if (left < right)
swap(arr, left, right);
}
// 此时left==right
if (left - 1 > start) quickSort(arr, start, left - 1);
if (right + 1 < end) quickSort(arr, right + 1, end);
}
public static void main(String[] args) {
// int[] arr = {3, 1, 9, 7, 13, 0, 24, 67, 33};
int arr[] = {6, 1, 2, 7, 4, 5, 10, 8};
int len = arr.length;
// insertSort(arr, len);
// bubbleSort(arr, len);
// mergeSort(arr, 0, len - 1);
// shellSort(arr, len);
// selectSort(arr, len);
// heapSort(arr, len);
quickSort(arr, 0, len - 1);
for (int a : arr) {
System.out.print(a + " ");
}
}
}