From 7f7557d34475094b42428f10d92c784659458f7d Mon Sep 17 00:00:00 2001 From: null796 <982254607@qq.com> Date: Tue, 15 Dec 2020 22:47:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A0=86=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 68 ++++++++++++++ Heap/src/Heap/HeapSort.java | 47 ++++++++++ Heap/src/Heap/MaxHeap.java | 178 ++++++++++++++++++++++++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 Heap/src/Heap/HeapSort.java create mode 100644 Heap/src/Heap/MaxHeap.java diff --git a/.gitignore b/.gitignore index be4e216..1244f90 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,71 @@ package-lock.json node_modules id.txt run.sh +# 忽略匹配下列规则的Git 提交 V2.1.0 +### gradle ### +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +### STS ### +.settings/ +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +*.lock +rebel.xml + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### maven ### +target/ +*.war +*.ear +*.zip +*.tar +*.tar.gz + +### logs #### +/logs/ +*.log + +### docker #### +/docker/ +*.jar + +### temp ignore ### +*.cache +*.diff +*.patch +*.tmp +*.java~ +*.properties~ +*.xml~ + +### system ignore ### +.DS_Store +Thumbs.db +Servers +.metadata +upload +gen_code + +### node ### +node_modules + diff --git a/Heap/src/Heap/HeapSort.java b/Heap/src/Heap/HeapSort.java new file mode 100644 index 0000000..a893f94 --- /dev/null +++ b/Heap/src/Heap/HeapSort.java @@ -0,0 +1,47 @@ +package Heap; + +public class HeapSort { + public static void main(String[] args) { + int[] nums = {16,7,3,20,17,8}; + headSort(nums); + for (int num : nums) { + System.out.print(num + " "); + } + } + + /** + * 堆排序 + */ + public static void headSort(int[] list) { + //构造初始堆,从第一个非叶子节点开始调整,左右孩子节点中较大的交换到父节点中 + for (int i = (list.length) / 2 - 1; i >= 0; i--) { + headAdjust(list, list.length, i); + } + //排序,将最大的节点放在堆尾,然后从根节点重新调整 + for (int i = list.length - 1; i >= 1; i--) { + int temp = list[0]; + list[0] = list[i]; + list[i] = temp; + headAdjust(list, i, 0); + } + } + + private static void headAdjust(int[] list, int len, int i) { + int k = i, temp = list[i], index = 2 * k + 1; + while (index < len) { + if (index + 1 < len) { + if (list[index] < list[index + 1]) { + index = index + 1; + } + } + if (list[index] > temp) { + list[k] = list[index]; + k = index; + index = 2 * k + 1; + } else { + break; + } + } + list[k] = temp; + } +} \ No newline at end of file diff --git a/Heap/src/Heap/MaxHeap.java b/Heap/src/Heap/MaxHeap.java new file mode 100644 index 0000000..827a9a7 --- /dev/null +++ b/Heap/src/Heap/MaxHeap.java @@ -0,0 +1,178 @@ +package Heap; + +import java.util.ArrayList; +import java.util.List; + +/** + * 大顶堆 + * + * @author tao + * + */ +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); + + } +} -- Gitee