《數據結構與面向對象程序設計》第九周學習總結

學號 2019-2020-1 《數據結構與面向對象程序設計》第九周學習總結

教材學習內容總結

  • 非線性數據結構——————樹,元素組織爲層次結構
  • 樹的基本概念
    • 概念:樹由一組結點和一組邊構成,經過結點來存儲元素,邊表示節點之間的鏈接
  • 樹的相關術語:
    • 根節點:樹中惟一沒有父節點的節點,位於樹的頂層
    • 內部結點:一顆樹中既不是根結點也不是葉結點的稱爲內部結點
    • 葉子:沒有孩子的結點稱之爲葉子
    • 高度/深度:一顆樹的層數
    • 度/階:一棵樹中任一結點所具備的最大孩子數目
  • 樹的分類
    • 分類標準:任一結點能夠具備的最大孩子數目,稱爲度。咱們主要學習二叉樹,即每一個結點下最多有兩個孩子的樹。
    • 徹底樹:底層葉子都位於樹的左邊的平衡樹稱爲徹底樹
    • 滿樹:在一顆n元樹中,全部葉子都位於一層,且除葉子外的每一個結點都有n個孩子,則該樹被稱做滿樹
    • 平衡:樹的全部葉子之間相差層數不超過一層的樹稱爲穩定的樹
  • 二叉樹
  • 性質
    • 二叉樹的每個結點最多具備兩個孩子結點
    • 在二叉樹的第i層最多有2i-1個結點
    • 深度爲k的二叉樹最多有2k-1個結點
    • 對任何一棵二叉樹,若是其葉結點個數爲n0,度爲2的結點數爲n2則有n0=n2+1
  • 徹底二叉樹
    • 對於深度爲K的,有n個結點的二叉樹,當且僅當其每個結點都與深度爲K的滿二叉樹中編號從1至n的結點一一對應時稱之爲徹底二叉樹
  • 滿二叉樹
    • 每層結點都是滿的二叉樹
  • 樹的遍歷(四種方法)
  • 二叉樹的遍歷(traversing binary tree)是指從根結點出發,按照某種次序依次訪問二叉樹中全部的結點,使得每一個結點被訪問依次且僅被訪問一次
    • 前序遍歷:若樹爲空,則空操做返回。不然,先訪問根節點,而後前序遍歷左子樹,再前序遍歷右子樹
    • 代碼實現
    public static void preOrderTraverse(Node root) {
          Stack<Node> stack = new Stack<>();
          Node node1 = root;
          while (node1 != null || !stack.empty()) {
              if (node1 != null) {
                  System.out.print(node1.val + " ");
                  stack.push(node1);
                  node1 = node1.left;
              } else {
                  Node tem = stack.pop();
                  node1 = tem.right;
              }
          }
      }
    • 中序遍歷:若樹爲空,則空操做返回。不然,從根節點開始(注意並非先訪問根節點),中序遍歷根節點的左子樹,而後是訪問根節點,最後中序遍歷根節點的右子樹
public static void inOrderTraverse(Node root) {
        Stack<Node> stack = new Stack<>();
        Node node1 = root;
        while (node1 != null || !stack.isEmpty()) {
            if (node1 != null) {
                stack.push(node1);
                node1 = node1.left;
            } else {
                Node tem = stack.pop();
                System.out.print(tem.val + " ");
                node1 = tem.right;
            }
        }
    }
  • 後續遍歷:若樹爲空,則空操做返回。不然,從左到右先葉子後節點的方式遍歷訪問左右子樹,最後訪問根節點
public static void postOrder(Node root) {
        if (root != null) {
            postOrder(root.left);
            postOrder(root.right);
            System.out.print(root.val + " ");
        }
    }
  • 層序遍歷:若樹爲空,則空操做返回。不然,從樹的第一層,也就是根節點開始訪問,從上到下逐層遍歷,在同一層中,按從左到右的順序結點逐個訪問
public static void levOrder(Node root) {
        if (root != null) {
            Node p = root;
            Queue<Node> queue = new LinkedList<>();
            queue.add(p);
            while (!queue.isEmpty()) {
                p = queue.poll();
                System.out.print(p.val + " ");
                if (p.left != null) {
                    queue.add(p.left);
                }
                if (p.right != null) {
                    queue.add(p.right);
                }
            }
        }
    }
  • 二叉查找樹
  • 概念:一棵具備下列性質的二叉樹:
    • 若左子樹不空,則左子樹上全部結點的值均小於它的根結點的值;
    • 若右子樹不空,則右子樹上全部結點的值均大於它的根結點的值;
    • 左、右子樹也分別爲二叉查找樹
    • 沒有元素相等的點
    • 也能夠這麼說:左孩子小於父結點,而父結點又小於或等於右孩子
      操做:
    • addElement:向樹中添加一個元素
    • removeElement:從樹中刪除一個元素
    • removeAllOccurrences:從樹中刪除所指定元素的任何存在
    • removeMin:刪除樹中的最小元素
    • removeMax:刪除樹中的最大元素
    • findMin:返回樹中的最小元素的引用
    • findMax:返回樹中的最大元素引用
  • 遞歸算法(調用本身):實現二叉查找樹算法比較方便
  • 非遞歸
  • 最優二叉樹/哈夫曼樹:平均帶權長度最短的二叉樹
    • 權值越大的編碼離根越近
    • 取兩個最小的,相加等於一個值,再重複排序插入html

      教材學習中的問題和解決過程

  • 問題1:平衡二叉查找樹有什麼做用以及如何實現?
  • 問題1解決方案:平衡二叉樹的概念:一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,而且左右兩個子樹都是一棵平衡二叉樹。若是普通的二叉查找樹在不斷插入後失去平衡,最終可能會變成鏈表的形式,使查找效率大大下降。(如右圖)因此咱們須要二叉樹保持平衡
  • 非平衡二叉查找樹改變成爲平衡二叉查找樹主要有四種方法:右旋,左旋,左右旋,右左旋
    • 右旋,一般是指左孩子繞着其父結點向右旋轉,通常適用於左子樹長於右子樹的狀況
    • 左旋,一般是指右孩子繞着其父結點向左旋轉,通常適用於右子樹長於左子樹的狀況
    • 王老師上課講到,能夠把二叉樹平衡理解爲轉動一條項鍊上的珠子。具體來講,就是左旋就是往左變換,右旋就是往右變換。不論是左旋仍是右旋,旋轉的目的都是將節點多的一支出讓節點給另外一個節點少的一支。
    • 這個還要根據具體實例進行細化研究,再深一步可能還要用到複雜的紅黑樹
  • 問題2:二叉查找樹刪除方法的實現比較複雜,如何考慮多種狀況刪除?
  • 問題2解決方案:分三種狀況進行討論
    • 若是刪除的是葉節點,能夠直接刪除
    • 若是被刪除的元素有一個子節點,能夠將子節點直接移到被刪除元素的位置,即應該調整要被刪除的父結點(指向被刪除結點的孩子結點
    • 若是有兩個子節點,這時候就採用中序遍歷,找到待刪除的節點的後繼節點,將其與待刪除的節點互換,此時待刪除節點的位置已是葉子節點,能夠直接刪除 。即用被刪除節點的右子樹的最小的數據替代要被刪除結點的數據,並遞歸刪除用於替換的結點(此時該結點已爲空)
    • 將待刪除節點與後繼節點互換,變成以下圖所示:
    • 將待刪除元素刪除
  • 問題3:遞歸和迭代的區別在哪裏?遞歸的優點是什麼?
  • 問題3解決方案:遞歸,其實就是函數本身調用本身。迭代是指利用變量的原值推算出變量的一個新值,能夠理解爲A不停的調用B。迭代使用的是循環(for,while,do-while)或者迭代器,當循環條件不知足時退出。而遞歸通常是函數遞歸,能夠是自身調用自身,只需有一個結束遞歸的條件。遞歸的優點是簡潔明瞭,缺點是浪費大量的空間,效率較低

代碼調試中的問題和解決過程

  • 問題1:在使用樹處理中綴表達式轉換爲後綴表達式中輸出出現了問題,toString方法沒法正常使用
    node

  • 問題1解決方案:經檢查toString方法,個人結點部分使用的是整型部分使用的是泛型,不適應於字符串型。也沒法進行正常的比較,最終只能再次重寫整個方法
  • 問題2:在編寫做業17.1時,遍歷時迭代器出現了問題
    git

  • 問題2解決方案:檢查迭代器的代碼,發現我照抄了書上的Iterator 類,將其修改成ArrayList 類便可正常運行
public ArrayList<T> inorder() {
        ArrayList<T> iter = new ArrayList<T>();

        if (root != null)
            root.inorder(iter);

        return iter;
    }

代碼託管

算法

express

上週考試錯題總結

  • Which of the following is not a valid postfix expression?
    • 4 + 5
    • 看錯了,是not
  • When one type of object contains a link to another object of the same type, the object is sometimes called __________ .
    • A self-referential object is one that refers to another object of the same type.
    • 自引用竟然能夠指向同一類型的不一樣目標,以前確實不理解
  • The import keyword is used to define your own packages.
    • The package keyword is used to define packages of source code in Java.
    • 理解錯誤,import是用來導入包中的源代碼
  • In a linked implementation of a stack, a pushed element should be added to the end of the list.
    • push操做應該放在最前面,不然沒法實現棧的後進先出(前面的有點學混了,要及時複習)

結對及互評

評分標準

  1. 正確使用Markdown語法(加1分):
    • 不使用Markdown不加分
    • 有語法錯誤的不加分(連接打不開,表格不對,列表不正確...)
    • 排版混亂的不加分
  2. 模板中的要素齊全(加1分)
    • 缺乏「教材學習中的問題和解決過程」的不加分
    • 缺乏「代碼調試中的問題和解決過程」的不加分
    • 代碼託管不能打開的不加分
    • 缺乏「結對及互評」的不能打開的不加分
    • 缺乏「上週考試錯題總結」的不能加分
    • 缺乏「進度條」的不能加分
    • 缺乏「參考資料」的不能加分
  3. 教材學習中的問題和解決過程, 一個問題加1分編程

  4. 代碼調試中的問題和解決過程, 一個問題加1分數據結構

  5. 本週有效代碼超過300分行的(加2分)
    • 一週提交次數少於20次的不加分
  6. 其餘加分:
    • 週五前發博客的加1分
    • 感想,體會不假大空的加1分
    • 排版精美的加一分
    • 進度條中記錄學習時間與改進狀況的加1分
    • 有動手寫新代碼的加1分
    • 課後選擇題有驗證的加1分
    • 代碼Commit Message規範的加1分
    • 錯題學習深刻的加1分
    • 點評認真,能指出博客和代碼中的問題的加1分
    • 結對學習狀況真實可信的加1分
  7. 扣分:
    • 有抄襲的扣至0分
    • 代碼做弊的扣至0分
    • 遲交做業的扣至0分

點評模板:

  • 博客中值得學習的或問題:
    • 問題探究不夠深刻
  • 代碼中值得學習的或問題:
    • 代碼commit不標準,缺乏註釋不宜看懂
  • 基於評分標準,我給本博客打分:16X分。得分狀況以下:xxx函數

  • 參考示例post

點評過的同窗博客和代碼

  • 本週結對學習狀況
    • 20182302
    • 結對學習內容
      • 書上二叉樹方法的補充
      • 實現平衡二叉樹的各類狀況
  • 上週博客互評狀況

其餘(感悟、思考等,可選)

  • 太難了,這堆算法環環相扣,思路也不大好理解。書上的方法補寫起來不容易,也不給一點提示。編程時知道大致的思路和具體實現是兩回事,苦於找不到正確的編程方法

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 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
第五週 1600/2900 2/11 20/110
第六週 981 /3881 2/12 25/135
第七週 1700/5518 3/15 45/180
第八週 700/6200 2/17 20/200
第九周 4300/10500 3/20 30/230

嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進本身的計劃能力。這個工做學習中很重要,也頗有用。
耗時估計的公式:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。學習

參考:軟件工程軟件的估計爲何這麼難軟件工程 估計方法

  • 計劃學習時間:30小時

  • 實際學習時間:30小時

  • 改進狀況:

(有空多看看現代軟件工程 課件
軟件工程師能力自我評價表
)

參考資料

相關文章
相關標籤/搜索