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

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

1、教材学习内容总结

相信其它不少同窗都是以小顶堆来介绍这一章内容,因此我将以大顶堆来介绍这章内容。html

1.1 堆的简单介绍:

  • 堆的定义:(大顶堆
    • 堆其实是一棵彻底二叉树。
    • 堆知足两个性质:
      1. 堆的每个父节点都大于其子节点;
      2. 堆的每一个左子树和右子树也是一个堆。
  • 堆的分类:
    • 堆分为两类:
      1. 最大堆(大顶堆):堆的每一个父节点都大于其孩子节点;
      2. 最小堆(小顶堆):堆的每一个父节点都小于其孩子节点;
    • 例子:

  • 堆的操做:
    • 堆的定义是二叉树的拓展,所以他也继承了二叉树的全部操做。
    • 操做列表(大顶堆为例):
    操做 说明
    addElement() 将给定元素添加到该堆中去
    removeMax() 删除堆中最大的元素
    findMax() 返回一个指向堆中最大元素的引用
  • addElement操做:
    • addElement方法将给定的Comparable元素添加到堆中的恰当位置,且维持该堆的彻底属性和有序属性。
    • 由于堆是一棵彻底二叉树,所以对于新插入的节点而言,就只有一个正确的位置,要么是h层左边的下一个空位置,要么是h+1层的第一个位置(此时h层已经装满了)。
    • 以下图:它有这两个位置可插入:
    • 一般在堆的实现中,咱们会对二叉树的最后一片叶子进行跟踪记录。
    • 最大堆的插入:
  • removeElement操做:
    • 对于大顶堆而言,删除最大元素即删除二叉树的根结点,若是删除根结点而要想维持堆的彻底性,必须与最后一片叶子进行交换位置。
    • 交换位置后,必须进行重排序、以维持堆的第二个属性:排序。
    • 用图表示下过程:
  • findMax操做java

    findMax操做将返回一个指向该最大堆中最大元素的引用,也就是根结点的引用。因此实现这一操做只需返回储存在根结点的元素便可。node

1.2使用堆:优先级队列。

  • 咱们先来举个例子来感觉下优先级队列。
    • 生活中,排队时讲究女士优先。
    • 游戏中,抽奖人民币玩家得到好东西的几率更大!
  • 好,咱们如今来讲什么是优先级队列:
    • 具备更高优先级的项目优先,好比女士、人民币玩家。
    • 具备相同优先级的项目使用先进先出的方法 肯定其排序。
  • 虽然最大堆根本就不是一个队列,可是他提供了一个高效的优先级队列实现。
  • 关键代码:git

    在我看来,这个比较的代码是重中之重的。数组

public int compareTo(PrioritizedObject obj) 
    {
      int result;
                
      if (priority > obj.getPriority())
          result = 1;
      else if (priority < obj.getPriority())
          result = -1;
      else if (arrivalOrder > obj.getArrivalOrder())
          result = 1;
      else
          result = -1;
      
      return result;
    }

1.3 用链表实现堆:

  • 由于咱们须要再插入元素后可以向上遍历树,所以结点中须要一个指向双亲结点的指针
public class HeapNode<T> extends BinaryTreeNode<T>
{
    public HeapNode<T> parent;//指向双亲的指针。

  
    public HeapNode(T obj) 
    {
        super(obj);
        parent = null;
    }
}
  • 咱们还须要一个可以跟踪该堆最后一片叶子 的指针:数据结构

    public HespNode lastNode;函数

  • 最大堆的各类操做:
    • addElement操做:
      • addElement操做完成三个任务:
        1. 再恰当位置添加一个元素。
        2. 对堆进行重排序。
        3. 将lastNode指针从新指向新的最末结点。
      • addElement操做的时间复杂度为:O(log n)
    • removeMax操做:
      • removeMax主要完成三个操做:
        1. 将最后一片叶子结点与根结点交换位置。
        2. 对堆进行重排序。
        3. 返回初始根元素。
      • removeMax操做的时间复杂度为:O(log n)
    • findMax操做的时间复杂度为O(log n)

1.4用数组实现堆:

  • 堆的储存通常都是用数组实现的。
  • 堆是基于二叉树实现的,在二叉树的数组视线中,对于任一索引值为n的结点,其左结点在2n+1的位置右结点在2n+2的位置
  • 用数组实现堆的操做与用链表实现堆的操做步骤同样。但值得注意的是:链表实现和数组实现的addElement操做时间复杂度虽然都为O(log n),,但实际上链表更快点。

1.5 使用堆:堆排序。

排序方法有两个部分构成:添加列表的每一个元素、一次删除一个元素。学习

堆排序的时间复杂度为O(log n).测试

  • 进入实战:还记得上次的一个实验,给咱们一个数组没让咱们造成一个大顶堆,以后让咱们排序:如今让咱们整理一下思路:
    • 首先给出咱们一个数组:[45,36,18,53,72,30,48,93,15,35]
    • 而后咱们应该按照它们的索引造成一个二叉树:
    • 而后重排序,获得一个大顶堆:

    • 每轮排序的结果能够这样表达:
    public class test {
     public static void main(String[] args) {
         BigArraryHeap<Integer> temp=new BigArraryHeap<Integer>();
         int[] list={36,30,18,40,32,45,22,50};
         Object[] list2 = new Object[list.length];
    
         //将数组中的元素添加到大顶堆中
         for (int i = 0; i < list.length; i++)
             temp.addElement(list[i]);
    
         System.out.println("大顶堆的输出结果为:"+ temp);
         System.out.println();
    
         for(int n = 0; n < list2.length; n++){
             list2[n] = temp.removeMax();
             String result = "";
             for(int a = 0; a <= n; a++){
                 result += list2[a] + " ";
             }
             System.out.println("第" + (n+1) + "次排序:" + temp + " ~ " + result);
         }
    
         System.out.println();
    
         System.out.print("最后排序结果: ");
         String result = "";
         for(int m = 0; m < list.length; m++){
             result += list2[m] + " ";
         }
         System.out.println(result);
       }
     }
    • 运行结果为:

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

  • 问题1:如何理解这段话,该怎样实现?.net

    一般在堆的实现中,咱们会对二叉树的最后一片叶子进行跟踪记录。

  • 问题1解决方案:

    就是在对堆进行删除操做的时候须要将根结点与最后一片叶子结点进行交换位置,因此每一次操做都得更新lastNode结点。

  • 问题2:书上介绍了用数组实现的堆排序,那么链表实现的堆排序应该怎样排序?
  • 问题2解决方案:书上数组对对进行排序是写了一个方法,当想要进行排序的时候直接调用这个方法就OK,而咱们选在在测试类里面直接进行排序,使用最大堆,取出最大堆输出,而后就能够直接输出。

    如图:

  • 问题三:在网上搜寻有关于书上的资料室,出现了这么一个尴尬场面:

    以后我点进去看了一下:

原来是讲解了有关:栈内存和堆内存。
讲了这么个些东西,来潦草的总结下:

  • ava把内存划分红两种:一种是栈内存,一种是堆内存
    在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。
  • 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的做用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间能够当即被另做他用。 - 堆内存用来存放由new建立的对象和数组。
  • 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
  • 在堆中产生了一个数组或对象后,还能够在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。
  • 引用变量就至关因而为数组或对象起的一个名称,之后就能够在程序中使用栈中的引用变量来访问堆中的数组或对象。
    (大概就看懂了这么多)

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

  • 问题1:如何用堆构建一个队列、栈?
  • 问题1解决方案:

    首先咱们得知道咱们必须运用优先级堆,而且每一次添加元素,优先级都加一(从0开始)。

  • 而后咱们根据队列、栈的特色来输出
    • 队列是一种先进先出的结构,因此咱们只要使用最小堆中的removeMin方法便可输出最早进去的元素。
    • 栈是一种先进后出的结构,因此咱们只要使用最大堆中的removeMax方法便可输出最后面进去的元素,由于它的优先级高,因此他在前面输出。
    • 结果
  • 问题二:符合把一个Object型数据转化为char类型数据?
  • 原问题是这样的我须要把Object operator= +转化为char型数据,可是若是直接转,好比这样(char)operator是会抛出CalssCastException错误的!
  • 以后解决办法是先转化成String 而后再转化成char类型。
//像这样:
String a = String.valueOf(ope.pop());//ope.pop()出来的是一个Object型数据。
           operator = a.charAt(0);

代码之家

代码托管

上周考试错题总结

第十章错题

  • 错题1及缘由:

    What type does "compareTo" return?
    A .int
    B .String
    C .boolean
    D .char

    错误缘由:comparaTo方法返回的是 -1,0,1
    return "a".comparaTo("b")>0false or ture

    第十一章错题

  • 第十二章错题

    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

    错误缘由:堆是一棵彻底二叉树、不是一颗二叉搜索树。本身瞎了眼!!!!

点评模板:

博客或代码中值得学习的或问题:

- 内容很详细,把堆介绍的很透彻,
- 运用丰富的图片表达思想、好比插入、删除结点的介绍。
- 提出问题有点少。

点评过的同窗博客和代码

  • 本周结对学习状况
    • 20172310
    • 结对学习内容
      • 第十二章内容:堆、优先级队列
      • 实验二:树的综合运用
  • 上周博客互评状况
    - 20172302
    - 20172308
    - 20172310

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

这一章比起前面相对比较简单,但本身不能松懈.哎,比较难受的是这两天的假期都要贡献给博客了~~~~~o(╥﹏╥)o

学习进度条(上学期截止7200)

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 260/0 1/1 05/05
第二周 300/560 1/2 13/18
第三周 212/772 1/4 21/39
第四周 330/1112 2/7 21/60
第五周 1321/2433 1/8 30/90
第六周 1024/3457 1/9 20/110
第七周 1024/3457 1/9 20/130
第八周 643/4100 2/11 30/170

参考资料

1.优先队列
2.堆排序
3.java 各类数据类型之间的转化
4.java中的栈与堆

相关文章
相关标签/搜索