• 20172332 2017-2018-2 《程序设计与数据结构》第八周学习总结


    20172332 2017-2018-2 《程序设计与数据结构》第八周学习总结

    教材学习内容总结

    第十二章 优先队列与堆

    • 1.最小堆:具有两个附加属性的一棵二叉树。

      • ①他是一棵完全树
      • ②对每一结点,它小于或等于其左孩子和右孩子。
    • 2.最小堆将其最小元素存储在该二叉树的根处,且其根的两个孩子同样也是最小堆。

    • 3.addElement操作:

      • ①维持该堆的完全性属性和有序属性,所以插入的元素位置只存在一个正确的位置,要不然在h层左边的下一个空位置,要不然在h+1层左边的第一个位置。
        下图中,左图这种类型的为h层左边的下一个空位置,右图这种类型的为h+1层左边的第一个位置。


    - ②添加的为Comparable元素。
    - ③添加之后进行排序(过程名叫筛选)
    - ④在堆实现中,一般会对树中的最末一个结点(最末一片叶子),进行跟踪记录。

    • 4.removeMin操作:

      • ①维持该堆的完全性,(删除最小的也就是删除根)能替换根的合法元素只有一个就是最末一片叶子上存储的元素。
      • ②删除之后进行排序(过程名叫筛选)
    • 5.findMin操作:

      • 最小堆中的最小元素存储在根中,所以只需要返回存储在根中的元素。
    • 6.最大堆的定义与性质同理可得。

    • 7.优先级队列:遵循两个排序规则的集合。

      • ①具有更高优先级的项目在先。
      • ②具有相同优先级的项目使用先进先出方法来确定其排序。
      • ③解决方案:(1)使用队列列表;(2)使用最小堆。
    • 8.用链表实现堆:为了在插入元素后能够向上遍历该树,对BinaryTreeNode进行扩展并添加一个双亲指针。

    • 9.用数组实现堆:首先检查可用空间,如有需要进行扩容。

    • 9.链表实现和数组实现的addElement操作的时间复杂度同为O(log n)。

    • 10.链表实现和数组实现的removeMin操作的复杂度同为O(log n)。

    • 11.findMin操作只需要返回一个引用,因此复杂度为O(1)。

    • 12.堆排序。

      • 最小堆排序结果为升序排序,最大堆排序结果为降序排序。
      • 复杂度为O(n log n)
      • heapSort方法的两部分构成:添加列表的每个元素,然后一次删除一个元素。
      • 也可以使用要排序的数组来构建一个堆,通过互换得出排序结果。
    • 13.二叉树的数组实现中,树的根位于位置0处,对于每一个结点n,n的左孩子将位于数组的2n+1位置处,n的右孩子将位于数组的2(n+1)位置处。

    教材学习中的问题和解决过程

    • 问题1:对getNextParentAdd操作代码的理解。
     HeapNode<T> result = lastNode;
            while ((result != root) && (result.getParent().getLeft() != result))
                result = result.getParent();
            if (result != root)
                if (result.getParent().getRight() == null)
                    result = result.getParent();
                else {
                    result = (HeapNode<T>) result.getParent().getRight();
                    while (result.getLeft() != null)
                        result = (HeapNode<T>) result.getLeft();
                }
            else
                while (result.getLeft() != null)
                    result = (HeapNode<T>) result.getLeft();
    
            return result;
    
    • 问题1解决方案:这个方法是为了得到插入结点的双亲结点,看代码会很抽象,插入之前的堆,也就几种情况,可以一个一个跟着代码走一边,了解过程。
      • ①下图中7的结点为lastNode,看while循环的判断条件,该结点不为根结点,但是该结点的双亲结点的左孩子是它自己,所以不进入循环。看if语句块的判断条件,首先不为根结点,该结点的双亲结点的右孩子也就是7结点的兄弟是空的,所以返回的值为7结点的双亲结点,从图中可以很明显的看出,插入元素位置的双亲结点的确是7结点的双亲结点。

    - ②下图中8的结点为lastNode,看while循环的判断条件,该结点不为根结点,该结点的双亲结点的左孩子不是它自己,所以进入循环。result等于8结点的双亲结点,也就是3结点,看while循环的判断条件,该结点不为根结点,该结点的双亲结点的左孩子是它自己,所以跳出循环。看if语句块的判断条件,首先不为根结点,该结点的双亲结点的右孩子不为空,所以result等于该结点的双亲结点的右孩子,也就是3结点的右兄弟4结点,它的左孩子为空所以,插入元素的位置的双亲结点为4结点,从图中也可看出。
    

    - ③这种情况同①,可以算作一种情况
    

    - ④下图中10的结点为lastNode,看while循环的判断条件,会发现要经过两次循环,最终result等于1的结点,然后进入if语句块,1结点的双亲结点的右孩子不为空,所以进入else,result等于1结点的双亲结点的右孩子,也就是它自己的右兄弟,也就是2结点。看while循环的判断条件,2的左孩子不为空,满足条件,所以进入循环,得出result为5结点,很显然与图中符合一致。
    

    - ⑤有一种特殊情况,就是只有根的情况,故lastNode为根结点,插入元素就是根结点的孩子,所以返回值就是根结点。
    - 右子树的情况与上面几种一样,故不再探究。
    
    • 问题2:对heapifyAdd操作的代码理解。
        private void heapifyAdd()
        {
            T temp;
            int next = count - 1;
            
            temp = tree[next];
            
            while ((next != 0) && 
    			(((Comparable)temp).compareTo(tree[(next-1)/2]) < 0))
            {
    
                tree[next] = tree[(next-1)/2];
                next = (next-1)/2;
            }
    
            tree[next] = temp;
        }
    
    • 问题2解决方案:将元素插入后,为了保持堆的有序性,会进行排序(筛选的过程)。找到插入元素的双亲结点进行比较,把插入元素放入temp暂存,如果比双亲结点小(或者大),则把双亲结点向下移(或者不动),直到找到双亲结点不动的情况,则找到该插入元素的位置,把temp给双亲结点的孩子。

    代码调试中的问题和解决过程

    • 无。

    代码托管


    22440

    上周考试错题总结

    • 1.Since a heap is a binary search tree, there is only one correct location for the insertion of a new node, and that is either the next open position from the left at level h or the first position on the left at level h+1 if level h is full.

    • A .True

    • B .Flase

    • 答案:B

    • 分析:插入元素只有一个正确的位置的原因是因为它是一棵二叉完全树,而不是因为是一颗二叉搜索树。

    • 2.After one pass on the numbers ( 5 3 9 5 ), what would be the result if you were to use Bubble Sort?

    • A .5 3 5 9

    • B .5 5 3 9

    • C .3 5 5 9

    • D .9 5 5 3

    • 答案:C

    • 分析:按索引值来走,先是比a[0]与a[1],需要把他俩交换,得到3 5 9 5,再比较a[1]和a[2],不动,再比较a[2]和a[3],需要交换,所以得到3 5 5 9

    点评过的同学博客和代码

    其他(感悟、思考等,可选)

    • 堆是树的引申,并不难理解

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 0/0 1/1 2/2
    第二周 1010/1010 1/2 10/12
    第三周 651/1661 1/3 13/25
    第四周 2205/3866 1/4 15/40
    第五周 967/4833 2/6 22/62
    第六周 1680/6513 1/7 34/96
    第七周 2196/8709 1/8 35/131
    第八周 1952/10661 2/9 49/180
    • 计划学习时间:20小时

    • 实际学习时间:49小时

    • 改进情况:这周有实验所以花费的时间很多。

    参考资料

  • 相关阅读:
    PHP中无限分类、无限回复评论盖楼的实现方法,thinkphp5.0无限分类实例
    PHP中session详解
    使用thinkPHP做注册程序的实例
    虾米盒子系统开发APP
    angular 使用base64密码加密
    开发中遇到的两种表格文本长度处理,即长文本截断
    树组件使用文件夹图标
    angular实现指定DIV全屏
    JS调用浏览器打印机
    使用blob二进制流的方式下载后台文件
  • 原文地址:https://www.cnblogs.com/yu757503836/p/9931948.html
Copyright © 2020-2023  润新知