diff --git "a/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/HeapSort.class" "b/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/HeapSort.class" new file mode 100644 index 0000000000000000000000000000000000000000..8fb758f9a8769c42eb4bc234802c17e6b7ed43f5 Binary files /dev/null and "b/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/HeapSort.class" differ diff --git "a/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/HeapSort.java" "b/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/HeapSort.java" new file mode 100644 index 0000000000000000000000000000000000000000..ff642e0aaf184f5ffe276a6cac00fbae39a250da --- /dev/null +++ "b/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/HeapSort.java" @@ -0,0 +1,54 @@ +package Shuju; + +/** + * @author 我 + * @data 2020/12/15 - 17:20 + */ +import java.util.Arrays; + + +public class HeapSort { + + public static void adjustHeap(int[] arr, int pos, int len){ + int temp = arr[pos];//保存当前要调整的节点,保持不变 + int child; + // 沿关键字较大的孩子结点向下筛选,将当前节点放置到合适的位置 + for(; pos*2+1 <= len; pos = child){ + child = pos*2 + 1; + if( child < len && arr[child] > arr[child+1]){ + // child为关键字中较小记录的下标 + child++; + } + + if(temp <= arr[child]){ + break; + } + //若子节点小,则交换 + arr[pos] = arr[child]; + } + + //通过上面的for循环找到了当前要调整的节点要存放的位置 + arr[pos] = temp; + } + + //时间复杂度O(n) + public static void heapSort(int [] arr){ + //创建最大堆 + for (int i = arr.length/2 - 1; i >= 0; i--) { + adjustHeap(arr, i, arr.length-1); + } + + //交换堆顶元素和最后一个元素并调整堆 + for (int i = arr.length - 1; i >= 0; i--) { + int temp = arr[0]; + arr[0] = arr[i]; + arr[i] = temp; + adjustHeap(arr, 0, i-1); + } + } + public static void main(String[] args) { + int a[] = {5,4,9,8,7,6,0,1,3,2}; + heapSort(a); + System.out.println(Arrays.toString(a)); + } +} \ No newline at end of file diff --git "a/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/MaxHeap.class" "b/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/MaxHeap.class" new file mode 100644 index 0000000000000000000000000000000000000000..984828b5276e2b07b2186622952d9daac5623fb1 Binary files /dev/null and "b/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/MaxHeap.class" differ diff --git "a/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/MaxHeap.java" "b/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/MaxHeap.java" new file mode 100644 index 0000000000000000000000000000000000000000..151dbca7274427f75beec298471e4baee37e3174 --- /dev/null +++ "b/\344\275\234\344\270\232/\346\216\250\346\216\222\345\272\217/MaxHeap.java" @@ -0,0 +1,177 @@ +package Shuju; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author 我 + * @data 2020/12/15 - 17:16 + */ +public class MaxHeap> { + private List mHeap; // 存放元素的动态数组 + + public MaxHeap() { + + this.mHeap = new ArrayList<>(); + } + + + /** + * 大顶堆的向上调整算法(添加节点的时候调用) 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。 + * + * @param start + * -- 被上调节点的起始位置(一般为数组中最后一个元素的索引) + */ + protected void filterup(int start) { + + int c = start; // 需要调整的节点的初始位置 + int p = (c - 1) / 2; // 当前节点的父节点的位置 + T tmp = mHeap.get(c); // 被调整节点的值 + + while (c > 0) { + // 父节点的值和被调整节点的值进行比较 + int cmp = mHeap.get(p).compareTo(tmp); + if (cmp >= 0) { + // 父节点大 + break; + } else { + // 被调整节点的值大,交换 + mHeap.set(c, mHeap.get(p)); + c = p; + p = (c - 1) / 2; + } + } + // 找到被调整节点的最终位置了 + mHeap.set(c, tmp); + } + + + /** + * 大顶堆的向下调整算法(删除节点的时候需要调用来调整大顶堆) + * 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。 + * + * @param start + * -- 被下调节点的起始位置(一般为0,表示从第1个开始) + * @param end + * -- 截至范围(一般为数组中最后一个元素的索引) + */ + protected void filterdown(int start, int end) { + + int c = start; // 被下调节点的初始位置 + int l = 2 * c + 1; // 左孩子节点的位置 + T tmp = mHeap.get(c); // 当前节点的值(大小) + + while (l <= end) { + // 当前节点的左右节点进行比较 + int cmp = mHeap.get(l).compareTo(mHeap.get(l + 1)); + // 取大的 + if (l < end && cmp < 0) { + l++; + } + // 当前节点和大的那个再比较一下 + cmp = tmp.compareTo(mHeap.get(l)); + if (cmp >= 0) { + // 当前节点大,不用动 + break; + } else { + // 当前节点小,交换 + mHeap.set(c, mHeap.get(l)); + c = l; // 更新当前节点的位置 + l = 2 * c + 1; // 更新当前节点的左孩子位置 + } + } + mHeap.set(c, tmp); + } + + + /** + * 向大顶堆中插入新元素 + * + * @param data + */ + public void insert(T data) { + + int insertIndex = mHeap.size(); // 获取插入的位置 + // 将新元素插入到数组尾部 + mHeap.add(data); + // 调用filterup函数,调整大顶堆 + filterup(insertIndex); + } + + + /** + * 删除大顶堆中的data节点 + * + * @param data + * @return 返回-1表示出错, 返回0表示删除成功 + */ + public int remove(T data) { + + // 大顶堆空 + if (mHeap.isEmpty()) { + return -1; + } + + // 获取data在数组中的索引 + int index = mHeap.indexOf(data); + if (index == -1) { + return -1; + } + + // 堆中元素的个数 + int size = mHeap.size(); + // 删除了data元素,需要用最后一个元素填补,然后调用filterdown算法进行调整 + mHeap.set(index, mHeap.get(size - 1)); // 用最后一个元素填补 + mHeap.remove(size - 1); // 删除最后一个元素 + + if (mHeap.size() > 1 && index < mHeap.size()) { + // 调整成大顶堆 + filterdown(index, mHeap.size() - 1); + } + return 0; + } + + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < mHeap.size(); i++) { + sb.append(mHeap.get(i) + " "); + } + return sb.toString(); + } + + public static void main(String[] args) { + + int a[] = {10, 40 ,30, 60, 90, 70, 20, 50 ,80}; + + //大顶堆 + MaxHeap maxHeap = new MaxHeap<>(); + + //添加元素 + System.out.println("=== 依次添加元素:"); + for(int i = 0; i < a.length; i++) { + System.out.println(a[i]); + maxHeap.insert(a[i]); + } + + //生成的大顶堆 + System.out.println("=== 生成的大顶堆:"); + System.out.println(maxHeap); + + //添加新元素85 + int data = 85; + maxHeap.insert(data); + System.out.println("=== 添加新元素" + data + "之后的大顶堆:"); + System.out.println(maxHeap); + + //删除元素90 + data = 90; + maxHeap.remove(data); + System.out.println("=== 删除元素" + data + "之后的大顶堆:"); + System.out.println(maxHeap); + + } +} + diff --git "a/\344\275\234\344\270\232/\350\277\233\351\230\266/MergeK.class" "b/\344\275\234\344\270\232/\350\277\233\351\230\266/MergeK.class" new file mode 100644 index 0000000000000000000000000000000000000000..75e049d60f661a715e8ce07a094d0df29cb7c0df --- /dev/null +++ "b/\344\275\234\344\270\232/\350\277\233\351\230\266/MergeK.class" @@ -0,0 +1,68 @@ +package sj; + +import java.util.Arrays; + +/** + 合并K个有序数组 + */ +public class MergeK { + + public static int[] merge(int[] arr1, int[] arr2){ + int length1 = arr1.length; + int length2 = arr2.length; + + int[] arr = new int[length1 + length2]; + int j = 0; + int k = 0; + int i = 0; + while (j < length1 && k < length2){ + if (arr1[j] <= arr2[k]){ + arr[i] = arr1[j]; + i++; + j++; + }else { + arr[i] = arr2[k]; + i++; + k++; + } + } + + //把还没有进行合并的元素直接添加到新数组的后面,可能出现一个数组有剩,另一个数组合并完毕 + while (j < length1){ + arr[i] = arr1[j]; + i++; + j++; + } + while (k < length2){ + arr[i] = arr2[k]; + i++; + k++; + } + + return arr; + } + //2.求⼀组动态数据集合的最⼤Top K + public static void topK(int[] merge,int k) { + int[] toparr = new int[k]; + for (int i = 0; i < k; i++) { + toparr[i]=merge[i]; + + } + System.out.println(Arrays.toString(toparr)); + + } +//测试 + public static void main(String[] args) { + int[] arr1 = {1,4,57,6}; + int[] arr2 = {3,5,5,0}; + int[] arr3 = {3,2,3,11}; + int[] arr4 = {6,7,3,7}; + + int[] merge1 = merge(arr1, arr2); + int[] merge2 = merge(arr3, arr4); + int[] merge = merge(merge1, merge2); + System.out.println(Arrays.toString(merge)); + System.out.println("执行topK:"); + MergeK.topK(merge, 5); + } +} \ No newline at end of file diff --git "a/\344\275\234\344\270\232/\350\277\233\351\230\266/MergeK.java" "b/\344\275\234\344\270\232/\350\277\233\351\230\266/MergeK.java" new file mode 100644 index 0000000000000000000000000000000000000000..75e049d60f661a715e8ce07a094d0df29cb7c0df --- /dev/null +++ "b/\344\275\234\344\270\232/\350\277\233\351\230\266/MergeK.java" @@ -0,0 +1,68 @@ +package sj; + +import java.util.Arrays; + +/** + 合并K个有序数组 + */ +public class MergeK { + + public static int[] merge(int[] arr1, int[] arr2){ + int length1 = arr1.length; + int length2 = arr2.length; + + int[] arr = new int[length1 + length2]; + int j = 0; + int k = 0; + int i = 0; + while (j < length1 && k < length2){ + if (arr1[j] <= arr2[k]){ + arr[i] = arr1[j]; + i++; + j++; + }else { + arr[i] = arr2[k]; + i++; + k++; + } + } + + //把还没有进行合并的元素直接添加到新数组的后面,可能出现一个数组有剩,另一个数组合并完毕 + while (j < length1){ + arr[i] = arr1[j]; + i++; + j++; + } + while (k < length2){ + arr[i] = arr2[k]; + i++; + k++; + } + + return arr; + } + //2.求⼀组动态数据集合的最⼤Top K + public static void topK(int[] merge,int k) { + int[] toparr = new int[k]; + for (int i = 0; i < k; i++) { + toparr[i]=merge[i]; + + } + System.out.println(Arrays.toString(toparr)); + + } +//测试 + public static void main(String[] args) { + int[] arr1 = {1,4,57,6}; + int[] arr2 = {3,5,5,0}; + int[] arr3 = {3,2,3,11}; + int[] arr4 = {6,7,3,7}; + + int[] merge1 = merge(arr1, arr2); + int[] merge2 = merge(arr3, arr4); + int[] merge = merge(merge1, merge2); + System.out.println(Arrays.toString(merge)); + System.out.println("执行topK:"); + MergeK.topK(merge, 5); + } +} \ No newline at end of file