zoukankan      html  css  js  c++  java
  • 20162320刘先润大二第9周学习总结

    学号20162320 《程序设计与数据结构》第8周学习总结

    教材学习内容总结

    一、堆

    堆是一棵完全二叉树,其中每个元素大于等于其所有子结点的值。准确的说这是最大堆(maxheap)的定义,堆还可以是最小堆(minheap),即每个元素都小于等于它的孩子

    堆有三种基本操作

    • 1.向堆中添加一个新元素
        策略:将元素添加为新的叶结点,同时保持树是完全树,然后将该元素向根的方向移动,与它的父结点对换,直到其中的元素大小关系满足要求为止。
    • 2.找到最大元素
    • 3.删除最大元素
        策略:由堆的特性得知,最大元素在根上,所以删除最大元素就是要删除根结点,然后将余下的两个分开的子树重新构造为堆。

    利用最后的叶结点来取代根,然后将其向下移动到合适的位置。

    二、堆的排序

     堆排序是先将一组元素一项项地插入到堆中,然后一次删除一个,因为元素最先从堆中删除(在最大堆中),从堆中得到的元素序列将是有序序列,而且是降序的,类似地,一个最小堆可用来得到升序的排序结果。
     算法思路:每次将堆的堆顶记录输出;同时调整剩余的记录,使他们重新排成一个堆。重复以上过程。
     1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无须区;
      2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
      3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。(转)

     public int[] heapSort(int[] array){
             array = buildMaxHeap(array); 
             for(int i=array.length-1;i>1;i--){  
                 int temp = array[0]; 
                 array[0] = array[i];
                 array[i] = temp;
                 adjustDownToUp(array, 0,i);  
             }
             return array;
         }
    

    代码实现思路:首先初始建堆,array[0]为第一趟值最大的元素, 将堆顶元素和堆低元素交换,即得到当前最大元素正确的排序位置,最后将剩余的元素整理成堆。

    三、优先队列

     优先队列(priority queue)是一个服从两个有序规则的集合。首先,具有更高优先级的项排在前面,其次,具有相同优先级的项按先进先出的规则排序。

    优先队列不是FIFO队列,它根据优先级排序元素,而不是根据它们进入队列的次序排序。

    可用多个队列来实现优先队列,具有相同优先级的项保存在一个队列中。对于这个问题的更好的解决方案是使用堆。如果按优先级进行排序,就能看出优先队列和堆之间存在的自然关系,但要注意的是,具有相同优先级的项采用先进先出的原则,并没有自动应用到堆中。


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

    • 问题1: 一个有n个结点的堆的插入和删除操作,时间复杂度是多少?为什么?
      解答:假设该二叉树总共有x层,当该二叉树为满二叉树的时候,插入和删除耗费的时间是最长的,那么则有:
      2^x - 1 = n;在最坏的情况下,我们插入一个元素是从第一层遍历到第n层,那么进行的操作次数是树的深度,而树的深度x = log(2)(n+1)(表示以2为底,以n+1为真数的对数),忽略常数,那么我们就求得插入时的最坏时间复杂度则为O(logn)级别。
    • 问题2:堆与二叉查找树的区别是什么?
      解答:具有n个结点的二叉查找树和堆都是约束了元素之间关系的二叉树。
        (1)二叉查找树的结点大于它的左子结点,并小于等于它的右子结点,而(最大)堆中的结点大于等于它的两个子结点。
        (2)二叉排序树的深度取决于给定集合的初始排列顺序,在最优情况的深度为log n(表示以2为底的对数),最坏情况下其深度为n;而堆的深度是为堆所对应的完全二叉树的深度log n 。
        (3)二叉排序树是为了实现动态查找而设计的数据结构,它是面向查找操作的,在二叉排序树中查找一个结点的平均时间复杂度是O(log n);堆是为了实现排序而设计的一种数据结构,它不是面向查找操作的,因而在堆中查找一个结点需要进行遍历,其平均时间复杂度是O(n)。

    代码学习中的问题及解决

    • 问题1:完成作业PP18.1,实现程序设计项目中的getMax()方法
      解答:
            HeapNode<T> node = new HeapNode<T>(element);
            HeapNode<T> newParent = null;
    if (root == null) root = node;
    else {
        newParent = ((HeapNode<T>)root).getParentAdd(last);
            if (newParent.left == null)
                newParent.setLeft(node);
            else
                newParent.setRight(node);
        }
    node.setParent(newParent);
    last = node;
    ((HeapNode<T>)root).heapifyAdd(last);
    }
    

    在LinkedMaxHeap类中已经给出了add的方法,可以知道add方法中引用HeapNode中排序的方法,将元素与其的左右子结点进行比较,若子结点大于父结点,则交换二者。所以建立测试用例中添加大小顺序不同的数入堆中就已经排好序,已知最大堆中根结点是最大元素,所以getMax()可以直接返回根结点。return root.getElement();

    • 问题2:完成PP18.5,实现堆排序算法
      public static class HeapSort {
            private int[] buildMaxHeap(int[] array) {
                //从最后一个节点array.length-1的父节点(array.length-1-1)/2开始,直到根节点0,反复调整堆
                for (int i = (array.length - 2) / 2; i >= 0; i--) {
                    adjustDownToUp(array, i, array.length);
                }
                return array;
            }
    
    
            private void adjustDownToUp(int[] array, int k, int length) {
                int temp = array[k];
                for (int i = 2 * k + 1; i < length - 1; i = 2 * i + 1) {
                    if (i < length && array[i] < array[i + 1]) {
                        i++;
                    }
                    if (temp >= array[i]) {
                        break;
                    } else {
                        array[k] = array[i];
                        k = i;
                    }
                }
                array[k] = temp;
            }
    
            public int[] heapSort(int[] array) {
                array = buildMaxHeap(array);
                for (int i = array.length - 1; i > 1; i--) {
                    int temp = array[0];
                    array[0] = array[i];
                    array[i] = temp;
                    adjustDownToUp(array, 0, i);
                }
                return array;
            }
    
            public void toString(int[] array) {
                for (int i : array) {
                    System.out.print(i + " ");
                }
            }
        }
    

    解答:首先初始建立最大堆,array[0]为第一趟值最大的元素, 将堆顶元素和堆低元素交换,即得到当前最大元素正确的排序位置,最后将剩余的元素整理成堆。

    • 1)将存放在array[0,...,n-1]中的n个元素建成初始堆;
    • 2)将堆顶元素与堆底元素进行交换,则序列的最大值即已放到正确的位置;
    • 3)但此时堆被破坏,将堆顶元素向下调整使其继续保持大根堆的性质,再重复第23步,直到堆中仅剩下一个元素为止。

    代码托管

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


    上周考试错题总结

    • 错题1:
    Which of the following best describes a balanced tree?
    A .A balanced trees has all nodes at exactly the same level.
    B .A balanced tree has no nodes at exactly the same level.
    C .A balanced tree has half of the nodes at one level and half the nodes at another level.
    D .A balanced tree has all of the nodes within one level of each other.
    E .none of the above correctly describe a balanced tree.
    

    解答:D,我选的是E,我认为ABCD四个选项描述平衡树的概念都不完整或片面。比如说答案A,尽管树的节点在同一层次上是平衡的,但并不是所有的平衡树都有这个属性。所有A错误。相对其他选项只有D是正确定义了平衡树。

    • 错题2:
    A .true
    B .false
    

    解答:B,这个题目答案应该是给错了,因为答案给的是在后序遍历中根是最后访问的一个元素,这应该和A选项符合。


    结对及互评

    点评过的同学博客和代码


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

    You have to fight to reach your dream. You have to sacrifice and work hard for it. 为了实现梦想,你必须奋斗;你必须做出牺牲,必须为之努力。调整心态,继续前行,未来加油。


    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 188 1/1 25 算法分析
    第二周 70/258 1/2 15/40 《构建之法》7-9章
    第三周 474/732 1/3 20/60 查找和排序
    第四五六周 1313/2045 4/7 12/72 栈和队列
    第七周 890/2935 1/8 14/86
    第八周 913/3848 1/9 20/106 二叉查找树
    第九周 890/3738 1/10 13/119
    第十周
    • 计划学习时间: 20+小时
    • 实际学习时间: 25小时

    (有空多看看现代软件工程 课件 软件工程师能力自我评价表)

    参考资料

  • 相关阅读:
    Webpack的组成部分 半 详解
    代码简洁之道:编写干净的 React Components & JSX
    大体量点位置数据动态聚合Binning可视化效果
    树莓派FRP服务器自启动失败原因及解决办法
    nopCommerce自学笔记(一、环境搭建)-BigIcicle
    NopCommerce4.3中文版资源
    利用阿里云防勒索备份文件->ibdata 和 frm 文件恢复 MySQL 数据库
    ubuntu mysql设置sql_mode
    Ubuntu16.04 中PHP7.0 安装pdo_mysql 扩展
    相邻两个生产计划之间的衔接问题
  • 原文地址:https://www.cnblogs.com/lxrlxr/p/7766224.html
Copyright © 2011-2022 走看看