目录

  • 思维导图链接
  • 6.堆结构与堆排序几个经典题目分析 总览
    • 题1:堆结构
      • 题目描述:
      • 代码实现
    • 题2:堆排序
      • 题目描述:
      • 代码实现
    • 题3:2. 对几乎有序的数组进行排序
      • 题目描述:
      • 代码实现

思维导图链接

算法与数据结构思维导图

参考左程云算法课程

6.堆结构与堆排序几个经典题目分析 总览

题1:堆结构

题目描述:

  • 用自定义数组实现堆结构

  • 题目扩展:堆中某个位置数边了,不知变大还是变小了
    如何恢复成原堆结构

    • 1.对改位置调用siftUp方法

      2.对改位置调用siftDown方法

代码实现

package class06;import class03.Code04_ArraytoStackAndQueue.Array;public class Code02_Heap{public static class MaxHeap <E extends Comparable <E>> { private Array<E> data;public MaxHeap(int capacity) {data = new Array<>(capacity);}public MaxHeap() {data = new Array<>();}//  - 返回堆中的元素个数public int getSize() {return data.getSize();}//  - 返回一个布尔值,表示堆中是否为空public boolean isEmpty() {return data.isEmpty();}//    - 返回完全二叉树的数组表示中,一个索引所表示的父亲节点的索引private int parent(int index) {return (index - 1) / 2;}// - 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引private int leftChild(int index) {    return 2 * index + 1;}//   - 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引private int rightChild(int index) {return 2 * index + 2;}// 向堆中添加元素,向上heapify过程,同时维护堆的性质public void add(E e) {data.addLast(e);// 因为调用的是辅助类动态数组,size已经在Array中维护了siftUp(data.getSize() - 1);}private void siftUp(int k) {// 往上heapify过程,主要k不能为根节点while(k > 0 && data.get(k).compareTo(data.get(parent(k))) > 0) {data.swap(k, parent(k));k = parent(k);}}// 查找堆中最大元素public E peek() {if(data.isEmpty()) {throw new IllegalArgumentException("can't findMax from an empty heap");     }return data.get(0);}// 向堆中删除最大元素public E poll() {E ret = peek();// 删除的逻辑是,先将最大元素用新变量保存,然后与最后一个元素交换,将最后一个元素删除,再堆化data.swap(0, data.getSize() - 1);data.removeLast();siftDown(data, 0, data.getSize()); // 向下堆化return ret;}// 向下heapfy,其中,heapSize为堆容器大小private void siftDown(Array<E> data, int k, int heapSize) {while(leftChild(k)< heapSize) {// 先比较左右子节点,取较大节点的索引int j = leftChild(k);if(j + 1 < heapSize && data.get(j + 1).compareTo(data.get(j)) > 0) j ++;// 处理父子节点,保证根节点最大if(data.get(j).compareTo(data.get(k)) > 0) {data.swap(j, k);}// 继续往下堆化,将改动的子节点作为根节点循环进行,另一个子节点完整不变k = j;   }}}
}

题2:堆排序

题目描述:

  • 用定义的堆实现排序

代码实现

package class06;public class Code03_HeapSort {public static class HeapSort {public static <E extends Comparable<E>> void sort(E[] arr) {if (arr == null || arr.length <= 2)return;// 1.原地堆化,空间复杂度为O(1)// 1.1 逐个添加进行堆化,时间O(n)
//          for(int i = 0; i < arr.length; i ++) {//              siftUp(arr, i);
//          }//1.2 一次性传入整个数组,将整个数组进行堆化//找非叶子节点,自下往上找;找到所有非叶子节点后,再自上往下交换进行堆化//i为所有非叶子节点,故如果i为右节点,下一步要处理以左节点为根节点的树//即所有非叶子节点排列规律是从右往左,从下往上,层Z字行排列for(int i = parent(arr.length - 1); i >= 0; i --) {siftDown(arr, i, arr.length);}// 排序for(int i = arr.length - 1; i > 0; i --) {swap(arr, 0, i);    // 先交换,将堆顶元素放到指定位置i,[i,n)排好序siftDown(arr, 0, i);  // 对新的大小的堆结构进行堆化,[i,n)数不参与}}// 自下往上堆化private static <E extends Comparable<E>>void siftUp(E[] arr, int k) {while(k > 0 && arr[k].compareTo(arr[parent(k)]) > 0) {swap(arr, k, parent(k));k = parent(k);}       }private static int parent(int k) {return (k - 1) / 2;}/*** 自上向下堆化实现* * @param <E>* @param arr ,最大堆结构* @param k,  向下堆化的起始根节点* @param heapSize,  最大堆容器的大小*/private static <E extends Comparable<E>> void siftDown(E[] arr, int k, int heapSize) {// n是新堆结构的大小,不能用data.length,data数组中一部分排好序的数不参与堆化while (2 * k + 1 < heapSize) {int j = 2 * k + 1; // 左子节点索引// 判断左右子节点哪个大if (j + 1 < heapSize && arr[j + 1].compareTo(arr[j]) > 0) {j++; // 如果右子节点大,j表示右节点}if (arr[k].compareTo(arr[j]) < 0) {swap(arr, k, j); // 以k为根节点的子二叉树,根节点最大}// 继续往下堆化,将改动的子节点作为根节点循环进行,另一个子节点完整不变k = j;}}private static <E> void swap(E[] data, int k, int j) {E t = data[k];data[k] = data[j];data[j] = t;}}
}

题3:2. 对几乎有序的数组进行排序

题目描述:

  • 已知一个几乎有序的数组。几乎有序是指,如果把数组排好顺序的话,
    每个元素移动的距离一定不超过k,并且k相对于数组长度来说是比较小的。

    请选择一个合适的排序策略,对这个数组进行排序。

代码实现

public static void sortedArrDistanceLessK(int[] arr, int k) {if (k == 0)return;// 1. 建立k+1个元素的小根堆PriorityQueue<Integer> heap = new PriorityQueue<Integer>();int index = 0; // 堆的边界位置[0,index),左闭右开for (; index <= Math.min(arr.length - 1, k); index++) {heap.add(arr[index]);}// 2. 弹出和弹入,依次从左往右排好序// 堆中在i位置的元素一定包括在堆中,且是堆顶元素int i = 0; // 数组中将要排序的位置for (; i < arr.length; i++) {if (index < arr.length) {arr[i] = heap.poll();   // 弹出最小放到i位置heap.add(arr[index++]); // 向右推进,继续向堆中弹入新元素} else {arr[i] = heap.poll(); // 弹出最后k个元素}}

算法与数据体系课笔记之-6.堆结构与堆排序相关推荐

  1. python算法攻略_算法基础及python实现笔记一(堆和DFS)

    排序及搜索 讲到排序搜索首先要认识 Python 的基本数据存储结构. NumPy and Pandas 包都提供一些容器可以利用. 堆 (stack) 先进后出原则.比如,一个吃货吃东西,一直吃一直 ...

  2. 【算法实践】他山之石, 可以攻玉 -- 利用完全二叉树快速实现堆排序

    前言 什么是堆 堆是一种数据结构,它是完全二叉树或者是近似完全二叉树的一种数据结构,树中每个结点的值都不小于(或不大于)其左右孩子结点的值. 何为完全二叉树 完全二叉树是一种特殊的二叉树,完全二叉树是 ...

  3. 重构机器学习算法的知识体系 - 《终极算法》读书笔记

    2019独角兽企业重金招聘Python工程师标准>>> 最近有幸从图书馆借阅了Pedro Domingos的<The Master Alogrithm>一书,这本书的中文 ...

  4. AI公开课:19.05.29 浣军-百度大数据实验室主任《AutoDL 自动化深度学习建模的算法和应用》课堂笔记以及个人感悟

    AI公开课:19.05.29 浣军 百度大数据实验室主任<AutoDL 自动化深度学习建模的算法和应用>课堂笔记以及个人感悟 导读        浣军博士,汉族,1975年出生于江苏苏州, ...

  5. 七月算法--12月机器学习在线班-第七次课笔记—最大熵

    七月算法--12月机器学习在线班-第七次课笔记-最大熵 七月算法(julyedu.com)12月机器学习在线班学习笔记 http://www.julyedu.com 转载于:https://www.c ...

  6. 七月算法--12月机器学习在线班-第五次课笔记—回归

    七月算法--12月机器学习在线班-第五次课笔记-回归 七月算法(julyedu.com)12月机器学习在线班学习笔记 http://www.julyedu.com 转载于:https://www.cn ...

  7. 高级算法日记2:第1次课笔记

    第一次课笔记 lecture:沈孝钧 record:孙相国 time: 2017/05/06 排序算法比较 Divide and Conquer 1 Principle of Divide and C ...

  8. 左程云老师算法课笔记(一)

    前言 仅记录学习笔记,如有错误欢迎指正. 最近,有点忙,也有点懈怠,还是要加油加油,共勉. 一.排序 异或 ^: 交换律:a^ b = b^a 结合律:(a^ b) ^ c = (a ^ c)^ b ...

  9. LeetCode左程云算法课笔记

    左程云算法课笔记 剑指Offer 位运算 ^运算符理解 寻找出现双中的单数 取出一个数最右边1的位置 找所有双出现中的两个单数 整数二进制奇数位偶数位交换 数组中全部出现k次返回出现一次的数 链表 判 ...

最新文章

  1. [C#]委托和事件(讲解的非常不错)
  2. CUDA 并行计算优化策略总结
  3. Construct Binary Tree from Inorder and Postorder Traversal
  4. Rose Study
  5. jsp 获取项目路径,java获取项目路径
  6. POJ2942 Knights of the Round Table 点双连通分量 二分图判定
  7. omnipay支付--支付宝支付
  8. 如何打造应对超大流量的高性能负载均衡?
  9. 设计灵感|如何在海报设计中正确使用双色调风格?
  10. easyui小清新俺也晒晒 视频管理软件bs项目
  11. mysql的优化_第十一篇(查询计划篇)
  12. 计算机休眠状态和关,win7系统关于睡眠和休眠这两种状态的区别
  13. java 拖拉机_拖拉机(升级)必胜之秘诀 - 淡泊明志,宁静致远 - JavaEye技术网站...
  14. **time_limited.sof文件
  15. MySQL高级部分理论知识细讲
  16. dell服务器510系统,dellr510服务器上安系统.docx
  17. 噩梦射手(SurvivalShooter)教程(十一)
  18. Ubuntu开机一直滚屏 关键词:pcieport.......
  19. MPP大规模并行计算数据库与分布式数据库的区别
  20. 北京理工大学计算机学院研究生孙灿,吴心筱_北京理工大学计算机学院

热门文章

  1. windows7 校验下载文件的sha512
  2. 死亡爱丽丝服务器维护,这天天维护的游戏有啥好玩? 《死亡爱丽丝》试玩
  3. 样本数据异常值处理的三种方法
  4. 进程同步之信号量机制(pv操作)
  5. 网易云音乐为何与口碑合作?“音乐+生活”才更有滋味
  6. Github的公钥连接,使用.ssh协议连接问题
  7. 数据库:行存储、列存储 利弊分析
  8. Naive UI 之 修改组件样式
  9. 百度2021批秋招笔试题解
  10. 连续出错的概率_连续抛硬币问题+三个概率题