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小时

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

参考资料

posted @ 2018-11-09 17:27  雲深不知处  阅读(231)  评论(0编辑  收藏  举报