Sorting (fast sorting, merging, heap) java code
- Fast sorting: the most basic division used for division. In an orderly situation, the efficiency is very low, the optimization plan, and the random selection of division elements
- Merge sort: recurse downward first, then merge two ordered arrays
- Heap sorting: construct a large top pile,
n/ 2-1
adjust the structure from bottom to top from the first non-leaf node , and adjust the structure from right to left; swap the top element and the end element + adjust the pile structure (adjust once, adjust 0 node, make it become again Big top pile)
import org.junit.Test;
import java.util.Arrays;
public class MySort {
@Test
//快速排序
public void test1() {
int[] a = {
49, 38, 65, 97, 76, 13, 27, 50};
mergeSort(a, 0, a.length - 1);
System.out.println("排好序的数组:");
for (int e : a)
System.out.print(e + " ");
}
private static void quickSort(int[] arr, int start, int end) {
// 递归终止条件
if (start >= end) {
return;
}
// 第一步,找出分区后枢轴的下标,比如[2,1,3],枢轴为2,分区后枢轴的下标为1
int pivotIndex = partition(arr, start, end);
// 第二步,对左子数组排序
quickSort(arr, start, pivotIndex - 1);
// 第三步,对右子数组排序
quickSort(arr, pivotIndex + 1, end);
}
private static int partition(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--;
}
if (left < right) {
arr[left] = arr[right];
left++;
}
// 从左往右扫描,寻找比枢轴元素大的,并填入新坑中
while (left < right && arr[left] < pivot) {
left++;
}
if (left < right) {
arr[right] = arr[left];
right--;
}
}
// 扫描完成后,将枢轴元素填入新坑中
arr[left] = pivot;
return left;
}
@Test
//并归排序
public void test2() {
int[] a = {
49, 38, 65, 97, 76, 13, 27, 50};
mergeSort(a, 0, a.length - 1);
System.out.println("排好序的数组:");
for (int e : a)
System.out.print(e + " ");
}
public void mergeSort(int[] a, int start, int end) {
if (start < end) {
//当子序列中只有一个元素时结束递归
int mid = (start + end) / 2;//划分子序列
mergeSort(a, start, mid);//对左侧子序列进行递归排序
mergeSort(a, mid + 1, end);//对右侧子序列进行递归排序
merge(a, start, mid, end);//合并
}
}
public void merge(int[] a, int left, int mid, int right) {
int[] tmp = new int[a.length];//辅助数组
int p1 = left, p2 = mid + 1, k = left;//p1、p2是检测指针,k是存放指针
while (p1 <= mid && p2 <= right) {
if (a[p1] <= a[p2])
tmp[k++] = a[p1++];
else
tmp[k++] = a[p2++];
}
while (p1 <= mid) tmp[k++] = a[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
while (p2 <= right) tmp[k++] = a[p2++];//同上
//复制回原素组
for (int i = left; i <= right; i++)
a[i] = tmp[i];
}
@Test
public void test3() {
int[] arr = {
7, 6, 7, 11, 5, 12, 3, 0, 1};
System.out.println("排序前:" + Arrays.toString(arr));
heapsort(arr);
System.out.println("排序前:" + Arrays.toString(arr));
}
//堆排序
public static void heapsort(int[] arr) {
//1.构建大顶堆
for (int i = arr.length / 2 - 1; i >= 0; i--) {
//从第一个非叶子结点从下至上,从右至左调整结构
adjustHeap(arr, i, arr.length);
}
//2.调整堆结构+交换堆顶元素与末尾元素
for (int j = arr.length - 1; j > 0; j--) {
swap(arr, 0, j);//将堆顶元素与末尾元素进行交换
adjustHeap(arr, 0, j);//重新对堆进行调整
}
}
//调整大顶堆
public static void adjustHeap(int[] arr, int i, int length) {
int temp = arr[i];//先取出当前元素i
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
//从i结点的左子结点开始,也就是2i+1处开始
if (k + 1 < length && arr[k] < arr[k + 1]) {
//如果左子结点小于右子结点,k指向右子结点
k++;
}
if (arr[k] > temp) {
//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
arr[i] = arr[k];
i = k;
} else {
break;
}
}
arr[i] = temp;//将temp值放到最终的位置
}
//交换元素
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}