• 2018-2019-1 20172316《程序设计与数据结构》第八周学习总结


    20172316 2018-2019-1《程序设计与数据结构》第八周学习总结

    教材学习内容总结

    第十二章 堆

    堆:

    堆是具有两个附加属性得的一棵二叉树:

    • 它是一棵完全树;
    • 对每一节点,它小(大)于或等于其左孩子和右孩子。

    堆的分类:按照堆中元素排列规律将堆分为两类:

    • 最小堆(minheap),本章介绍中默认的堆的类型,对每一节点,它小于或等于其左孩子和右孩子

    • 最大堆(maxheap),与最小堆相反(对每一节点,它大于或等于其左孩子和右孩子)

    优先级队列(priority queue):
    排序规则:

    • 具有更高优先级的项在前;
    • 具有相同优先级的项目按照先进先出方法来确定排序。

    回顾知识点:完全树,树最底层的叶子都在树的左边

    堆接口的方法(最小堆)

    操作 说明
    addElement 将给定元素添加到该堆中
    removeMin 删除堆中的最小元素
    findMin 返回一个指向堆中最小元素的引用

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

    1. 创建一个堆之后进行多次addElement()操作添加元素后,还需要进行重排序?

    选择数组addElement()分析,较为简短:

    public void addElement(T obj) 
        {
            if (count == tree.length)
                expandCapacity();
    
            tree[count] = obj;
            count++;
    	    modCount++;
    
            if (count > 1)
                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;
        }
    
    

    检查代码,发现:在插入过程中addElement()方法引用了heapifyAdd()方法,addElement()方法仅作插入,将指定元素放到最末节点,如果不进行重排序,堆就不一定会符合小项在上的规则。

    重排序和插入是同时进行的,而不是我之前理解的:先插入后排序

    同样的问题,removeMin()方法删除最小元素(最顶端),要维持堆的完全性,替换它的元素是最末的元素,此时也需要进行重排序:

    private void heapifyRemove()
        {
            T temp;
            int node = 0;
            int left = 1;
            int right = 2;
            int next;
            
            if ((tree[left] == null) && (tree[right] == null))
                next = count;
            else if (tree[right] == null)
                next = left;
            else if (((Comparable)tree[left]).compareTo(tree[right]) < 0)
                next = left;
            else
                next = right;
            temp = tree[node];
    
            while ((next < count) && 
    			(((Comparable)tree[next]).compareTo(temp) < 0))
            {
                tree[node] = tree[next];
                node = next;
                left = 2 * node + 1;
                right = 2 * (node + 1);
                if ((tree[left] == null) && (tree[right] == null))
                    next = count;
                else if (tree[right] == null)
                    next = left;
                else if (((Comparable)tree[left]).compareTo(tree[right]) < 0)
                    next = left;
                else
                    next = right;
            }
            tree[node] = temp;
        }
    
    

    removeMin()方法涉及到最末和顶部元素替换,重排序的过程也会相对复杂。


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

    1. “既然用数组实现堆时,使用了数组进行储存,为什么不能直接用这样的方法来导入元素↓?”
    public void ArrayToHeap(T[] array) {
            tree = array;
            count = tree.length + 1;
        }
    
    

    后面产生了一系列问题,但是使用书本上的addElement()方法插入时则不会出错,后来仔细研究addElement()才发现问题所在:直接导入的数组不一定符合堆的性质,而使用addElement()方法由于重排序的存在可以很好地解决这一问题。


    代码托管

    (statistics.sh脚本的运行结果截图)


    上周考试错题总结

    • Insertion sort is an algorithm that sorts a list of values by repetitively putting a particular value into its final, sorted, position.
      答案:false
      )并不是直接放入最终排序位置。

    • There are only two ways that a tree, or any subtree of a tree, can become unbalanced: through the insertion of a node or through the deletion of a node.
      答案:true
      )书中原话。


    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 0/0 1/1 6/6
    第二周 771/771 1/2 16/22
    第三周 562/1233 1/3 15/37
    第四周 1503/2736 2/5 15/52
    第五周 1152/3888 1/6 10/62
    第六周 787/4675 1/7 10/72
    第七周 1214/5889 1/8 9/81
    第八周 1534/7423 1/9 9/90

    结对互评

    唐才铭19
    王文彬29

    参考资料

  • 相关阅读:
    Java 中的 volatile 关键字
    Java 隐式锁
    导致并发程序出问题的根本原因是什么?
    BZOJ_2434_[Noi2011]阿狸的打字机_AC自动机+出栈入栈序+树状数组
    BZOJ_5368_[Pkusc2018]真实排名_组合数
    CF上的3道小题(2)
    BZOJ_4199_[Noi2015]品酒大会_后缀自动机
    BZOJ_4566_[Haoi2016]找相同字符_后缀自动机
    BZOJ_3172_[Tjoi2013]单词_后缀自动机
    BZOJ_3998_[TJOI2015]弦论_后缀自动机
  • 原文地址:https://www.cnblogs.com/zhaoqianchen/p/9940771.html
Copyright © 2020-2023  润新知