20162327 《程序设计与数据结构》第九周学习总结

20162327 2017-2018-1 《程序设计与数据结构》第九周学习总结

教材学习内容总结

  • 1、堆是一棵完全二叉树,其中每个元素大于等于其所有的子结点的值
  • 2、向堆中添加一个元素的方法是,首先将这个元素添加为叶节点,然后将其向上移动到合适的位置
  • 3、从堆中删除最大元素的方法是,利用最后的叶节点来取代根,然后将其向下移动到合适的位置
  • 4、堆排序利用堆得基本特性堆一组元素进行排序
  • 5、优先队列不是FIFO队列。它根据优先级排列元素,而不是根据他们进入队列的次序来排列

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

  • 问题1:对于堆的概念的理解
  • 问题1解决方案:
  1. 堆是一棵完全二叉树,二叉排序树不一定是完全二叉树;
  2. 在二叉排序树中,某结点的右孩子结点的值一定大于该结点的左孩子结点的值,在堆中却不一定;
  3. 在二叉排序树中,最小值结点是最左下结点,最大值结点是最右下结点。在堆中却不一定。
  • 问题2:对于哈夫曼树的理解
  • 问题2解决方案:
    ① 结点路径:从树中一个结点到另一个结点的之间的分支构成这两个结点之间的路径。
    ② 路径长度:结点路径上的分支数目称为路径长度。
    ③ 树的路径长度:从树根到每一个结点的路径长度之和。
    例图6-23的树。A到F :结点路径AEF;路径长度(即边的数目) 2;树的路径长度:3´1+5´2+2´3=19
    ④结点的带权路径长度:从该结点的到树的根结点之间的路径长度与结点的权(值)的乘积。
    权(值):各种开销、代价、频度等的抽象称呼。
    ⑤树的带权路径长度:树中所有叶子结点的带权路径长度之和,记做:
    WPL=w1´l1+w2´l2+⋯+wn´ln=∑wi´li (i=1,2,⋯,n)
    其中:n为叶子结点的个数;wi为第i个结点的权值;li为第i个结点的路径长度。
    ⑥ Huffman树:具有n个叶子结点(每个结点的权值为wi) 的二叉树不止一棵,但在所有的这些二叉树中,
    必定存在一棵WPL值最小的树,称这棵树为Huffman树(或称最优树)

教材中出现的代码问题及解决过程

  • 问题一:如何用哈夫曼树进行编码和解码
  • 解决方案:
 public String encode(String text)
    {
        String compressed="";                              //被压缩的数据,以字符串显示
        for (int i=0; i<text.length(); i++)
            compressed += getCode(text.charAt(i)-'A');     //默认字符集是从A开始的n个字符
        return compressed;
    }

    //数据解压缩,将压缩compressed中的0/1序列进行Huffman译码,返回译码字符串
    public String decode(String compressed)
    {
        String[]arr = new String[charset.length()];
        String str ="";
        for(int i=0;i<arr.length;i++){
            arr[i] = getCode(i);
        }
        ArrayList<Character> list = new ArrayList<>();
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        Map<String,String> map = new HashMap<>();
        for(int i=0;i<arr.length;i++){
            map.put(arr[i],((char)('A'+i))+"");
        }
        for(int i=0;i<compressed.length();i++) {
            list.add(compressed.charAt(i));
        }
        String temp = "";
        for(int i=0;i<list.size();i++){
            temp += list.get(i);
            if(OP(temp,arr)) {
                list1.add(temp);
                temp = "";
            }
        }
        for(String i:list1)
            list2.add(map.get(i));
        for(String i:list2)
            str += i;
        return str;
    }

    public boolean OP(String msg,String []arr){
        boolean result = false;
        for(int i=0;i<arr.length;i++) {
            result = msg.equals(arr[i]);
            if(result)
                break;
        }
        return result;
    }

问题二:如何获取堆中最大的元素

 public T getMax() throws Exception {
         if (root == null)
             throw new Exception ("没有元素");
         T maxElement = root.getElement();

         if (root.count() == 1)
             root = last = null;
         else
         {
             HeapNode<T> newLast = ((HeapNode<T>)root).getNewLastNode(last);
             if (last.parent.left == last)
                 last.parent.left = null;
             else
                 last.parent.right = null;
             root.setElement(last.getElement());
             last = newLast;
         }

         return maxElement;


     }

代码托管

本周结对学习情况

其他

  • 学习了很多和树有关的知识,有增加了堆和优先队列这个概念,自己需要好好整理整理了。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 300/500 2/4 18/38
第三周 500/1000 3/7 22/60
第四周 300/1300 2/9 30/90

参考:软件工程软件的估计为什么这么难软件工程 估计方法
(有空多看看现代软件工程 课件
软件工程师能力自我评价表
)

参考资料

posted @ 2017-11-05 21:20  小飞侠WJH  阅读(192)  评论(0编辑  收藏  举报