Add 希尔 归并 快速 堆

master
m6c9ftuqe 4 years ago
parent 4edb8cd20e
commit d23bcdabe5

@ -0,0 +1,168 @@
//希尔排序
public class ShellSort
{
public static int[] shellSort(int arr[]) {
if (arr == null || arr.length < 2) return arr;
int n = arr.length;
// 对每组间隔为 h的分组进行排序刚开始 h = n / 2;
for (int h = n / 2; h > 0; h /= 2) {
//对各个局部分组进行插入排序
for (int i = h; i < n; i++) {
// 将arr[i] 插入到所在分组的正确位置上
insertI(arr, h, i);
}
}
return arr;
}
/**
* 将arr[i]插入到所在分组的正确位置上
* arr[i]] 所在的分组为 ... arr[i-2*h],arr[i-h], arr[i+h] ...
*/
private static void insertI(int[] arr, int h, int i) {
int temp = arr[i];
int k;
for (k = i - h; k >= 0 && temp < arr[k]; k -= h) {
arr[k + h] = arr[k];
}
arr[k + h] = temp;
}
}
//归并排序
public class MergeSort {
// 归并排序
public static int[] mergeSort(int[] arr, int left, int right) {
// 如果 left == right表示数组只有一个元素则不用递归排序
if (left < right) {
// 把大的数组分隔成两个数组
int mid = left + (right - left) / 2;
// 对左半部分进行排序
arr = mergeSort(arr, left, mid);
// 对右半部分进行排序
arr = mergeSort(arr, mid + 1, right);
//进行合并
merge(arr, left, mid, right);
}
return arr;
}
// 合并函数,把两个有序的数组合并起来
// arr[left..mif]表示一个数组arr[mid+1 .. right]表示一个数组
private static void merge(int[] arr, int left, int mid, int right) {
//先用一个临时数组把他们合并汇总起来
int[] a = new int[right - left + 1];
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right) {
if (arr[i] < arr[j]) {
a[k++] = arr[i++];
}
else {
a[k++] = arr[j++];
}
}
while (i <= mid) a[k++] = arr[i++];
while (j <= right) a[k++] = arr[j++];
// 把临时数组复制到原数组
for (i = 0; i < k; i++) {
arr[left++] = a[i];
}
}
}
//快速排序
public class QuickSort {
public static int[] quickSort(int[] arr, int left, int right) {
if (left < right) {
//获取中轴元素所处的位置
int mid = partition(arr, left, right);
//进行分割
arr = quickSort(arr, left, mid - 1);
arr = quickSort(arr, mid + 1, right);
}
return arr;
}
private static int partition(int[] arr, int left, int right) {
//选取中轴元素
int pivot = arr[left];
int i = left + 1;
int j = right;
while (true) {
// 向右找到第一个大于等于 pivot 的元素位置
while (i <= j && arr[i] <= pivot) i++;
// 向左找到第一个小于等于 pivot 的元素位置
while (i <= j && arr[j] >= pivot) j--;
if (i >= j)
break;
//交换两个元素的位置使得左边的元素不大于pivot,右边的不小于pivot
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
arr[left] = arr[j];
// 使中轴元素处于有序的位置
arr[j] = pivot;
return j;
}
}
//堆排序
public class Head {
public static int[] headSort(int[] arr) {
int n = arr.length;
//构建大顶堆
for (int i = (n - 2) / 2; i >= 0; i--) {
downAdjust(arr, i, n - 1);
}
//进行堆排序
for (int i = n - 1; i >= 1; i--) {
// 把堆顶元素与最后一个元素交换
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
// 把打乱的堆进行调整,恢复堆的特性
downAdjust(arr, 0, i - 1);
}
return arr;
}
//下沉操作
public static void downAdjust(int[] arr, int parent, int n) {
//临时保存要下沉的元素
int temp = arr[parent];
//定位左孩子节点的位置
int child = 2 * parent + 1;
//开始下沉
while (child <= n) {
// 如果右孩子节点比左孩子大,则定位到右孩子
if (child + 1 <= n && arr[child] < arr[child + 1])
child++;
// 如果孩子节点小于或等于父节点,则下沉结束
if (arr[child] <= temp) break;
// 父节点进行下沉
arr[parent] = arr[child];
parent = child;
child = 2 * parent + 1;
}
arr[parent] = temp;
}
}
Loading…
Cancel
Save