From d23bcdabe5e78f56fb1f9615d0db4be74ca45cc0 Mon Sep 17 00:00:00 2001 From: m6c9ftuqe <2467047346@qq.com> Date: Fri, 18 Feb 2022 11:01:15 +0800 Subject: [PATCH] =?UTF-8?q?Add=20=E5=B8=8C=E5=B0=94=20=E5=BD=92=E5=B9=B6?= =?UTF-8?q?=20=20=E5=BF=AB=E9=80=9F=20=20=E5=A0=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 希尔 归并 快速 堆 | 168 +++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 希尔 归并 快速 堆 diff --git a/希尔 归并 快速 堆 b/希尔 归并 快速 堆 new file mode 100644 index 0000000..e68d5db --- /dev/null +++ b/希尔 归并 快速 堆 @@ -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; + } +} +