20172301 《程序設計與數據結構》第六週學習總結

20172301 《程序設計與數據結構》第六週學習總結

教材學習內容總結

  • 樹的概述
    • 樹由一個包含結點的集構成。 樹中結點和邊的關係是:總邊數 = 總結點數 - 1。
    • 根結點:就是指位於該樹頂層的惟一結點。一棵樹只有一個根結點,根結點沒有父節點。
    • 子結點:一個樹中較低層的結點是上一層結點的子結點。也叫做其孩子。
    • 兄弟結點:同一雙親的兩個結點。
    • 葉結點:沒有任何子結點的結點。
    • 內部節點:一個至少有一個子結點的非根節點。
    • 路徑長度:經過計算從根到該結點所必須越過的邊數目。
    • 高度:從根到葉子之間的最遠路徑的長度。
    • :樹中任一結點能夠具備的最大孩子的數目。
    • 含有m個元素的平衡n元樹具備的高度爲lognm。
  • 樹的分類:
    • 二叉樹:結點最多具備兩個孩子的樹。
    • 廣義樹:對結點所含有的孩子數目沒有限制的樹。
    • 平衡樹:粗略的來講,若是樹的葉子都位於同一層或者至少彼此相差不超過一層,那麼就稱之爲平衡的。
    • 徹底樹:若是某樹是平衡的,且底層全部葉子都位於樹的左邊,則認爲該樹是徹底的。 徹底二叉樹在每一個k層上都有2^k個結點,最後一層除外,在最後一層的結點必須是最左邊的結點。
    • 滿樹:若是一顆n元樹的全部葉子都位於同一層且每一結點要麼是一片葉子,要麼是正好具備n個孩子。 滿樹必定是徹底樹。
  • 樹的數組實現
    • 計算策略:對某些特定類型的樹,特別是二叉樹而言,二叉樹的存儲設從0開始,左子樹爲(2*n+1),右子樹爲(2*n+2). 可是,會浪費大量的存儲空間,最好用於滿樹。
    • 模擬連接策略:每個結點存儲的將是每個孩子(可能還有雙親)的數組索引,而不是指向其孩子(可能還有雙親)的指針對象的引用變量,可是該方式增長了刪除樹中元素的成本。 模擬連接策略容許連續分配數組位置而不用考慮樹的徹底性。
  • 樹的遍歷:
    • 前序遍歷:從根結點開始,訪問每個結點及其孩子。(A->B->D->E->C)
    Visit node   
    Traverse(left child) 
    Traverse(right child)
    • 中序遍歷:從根結點開始,訪問結點的左側孩子,而後是該結點,再而後是任何剩餘的結點。(D->B->E->A->C)
    Traverse(left child) 
    Visit node 
    Traverse(right child)
    • 後序遍歷:從根結點開始,訪問結點的孩子,而後是該結點。(D->E->B->C->A)
    Traverse(left child) 
    Traverse(right child) 
    Visit node
    • 層序遍歷:從根節點開始,訪問每一層的全部結點,一次一層。(A->B->C->D->E)
  • 二叉樹性質:
    • 性質1:在二叉樹的第i層上至多有2^(i-1)個結點(i>=1)。
    • 性質2:深度爲k的二叉樹至多有2^k-1個結點(k>=1)。
    • 性質3:對任何一顆二叉樹,若是其葉子結點數爲n0,度爲2的 結點 數爲n2,則n0 = n2+1.
  • 徹底二叉樹性質:
    • 性質1:具備n個結點的徹底二叉樹深度爲[log2n]+1 ([x]表示不 大於 x的最大整數)。
    • 性質2:若是對一顆有n個結點的徹底二叉樹(其深度爲[log2n]+1) 的結點按層序編號(從第1層到第[log2n]+1層,每層從左到右),對任意一個結點i(1<=i<=n)有:
      1).若是i=1,則結點i是二叉樹的根,無雙親;若是i>1,則其雙親是結 點[i/2]
      2).若是2i>n,則結點i無左孩子(結點i爲葉子結點);不然其左孩 子是結點2i。
      3).若是2i+1>n,則結點i無右孩子;不然其右孩子是結點2i+1。

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

  • 問題1:書P189 樹的數組實現中模擬連接策略裏提到了兩個名詞基準地址偏移量。應該是與文件存儲讀取時相關的有關名詞。
  • 問題1解決方案:
    • 網上並無查到合適的有關基準地址的定義。
    • 偏移量:計算機彙編語言中的偏移量定義爲把存儲單元的實際地址與其所在段的段地址之間的距離稱爲段內偏移,也稱爲「有效地址或偏移量」。
      html

    • 如圖,段地址左移四位,與 有效地址相加,就構成了邏輯地址。通常而言,段地址是cpu本身獨立編制的,可是偏移量是程序員編寫的。偏移量就是程序的邏輯地址與段首的差值。
    • 沒有理解,後期學習深刻探究。
  • 問題2:書P201 termType做用?
  • 問題2解決方案:在表達式樹中,斷定是不是操做符運用的方法是判斷termType變量是否爲1。
    • 我知道termType變量是人爲設定的。記得當時咱們實現四則運算的時候,判斷是不是操做符的條件是a.equals("+") || a.equals("-") || a.equals("*") || a.equals("÷"),我不以爲若是本身須要新建對象再肯定termType變量爲1是否更加簡便。
  • 問題3:書P200 printTree代碼如何理解?
  • 問題3解決方案:咱們老是一看到很長的代碼,就會沒有閱讀它的慾望。就像長篇的英語閱讀同樣。可是,不管它多長,它都是有規律可循的。須要咱們耐下性子,靜下心思去推敲,清楚每個變量的做用,清楚每個循環的跳出條件。抽絲剝繭, 把代碼分紅部分。
    • 咱們首先要清楚每個變量的意義。nodes是存儲樹中各個結點所指向的元素,possibleNodes是最大結點數+1,levelList是存儲各個元素它所對應的層數位置,currentLevel和previousLevel共同在決定着是否該換行 ,便是否該跳至下一行。
    int possibleNodes = (int)Math.pow(2, printDepth + 1);
    若是你清楚二叉樹的性質,你就會清楚這是最大的結點數加1。
    • 首先,判斷第0層,從根節點開始,不斷循環,從左到右,依次輸出空格和樹中的元素。
    • 具體的循環過程,我看了侯澤洋同窗的博客,寫的很是詳細,我便再也不過多贅述。傳送門

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

  • 問題1:背部疼痛診斷器找不到文件。
  • 問題1解決方案:
    • 這是一個小錯誤,原本我還覺得文件名字和文件添加位置不對。實際上,雖然我把txt文件和診斷器程序放在了一個文件夾裏面,可是他仍是不能直接經過名字進行查找。
    • 小組成員段志軒同窗告訴我,用絕對地址就能夠確保能夠查找到文件。
    • 我走進了思惟誤區,覺得txt文件的存放方式不對,而並無考慮地址的問題。
  • 問題2:小組成員段志軒同窗問我heght(BinaryTreeNode<T> node)方法中的遞歸是如何實現。由於if條件是node == null,那麼到最後是否是返回的值是0?
// 返回這棵樹的高度。
    public int getHeight()
    {
        return height(root);
    }

    // 返回指定節點的高度。
    private int height(BinaryTreeNode<T> node)
    {
        int left;
        int right;
        if (node == null)
        {
            return 0;
        }
        else
        {
            left = height(node.getLeft());
            right = height(node.getRight());
            if (left < right)
                return right + 1;
            else
                return left + 1;
        }
    }
  • 問題2解決方案:
    • 我特地作了一遍調試。
    • 這個方法是從根節點開始調用遞歸,而後一直找左子樹,直到左子樹爲null。
    • 能夠觀察到這裏left已經爲null了,那麼下一個判斷它將返回0。
    • 果真,left爲0,這時候開始遞歸right
    • 一直到左右都爲0的時候,也就是沒有左右孩子的時候,這時候個人返回值是right + 1,因此不會存在高度輸出爲0的結果。因此是正確的。手動@段志軒同窗。
  • 問題3:背痛診斷器拋出異常
Exception in thread "main" java.lang.ClassCastException: week6.BinaryTreeNode cannot be cast to java.base/java.lang.String

沒法轉換成String類型。DecisionTree類中evaluate()方法中的System.out.println (current.getRootElement());報錯。對於LinkedBinaryTree中的getRight()getLeft()方法,我一開始寫了兩種實現方法。可是在運行背痛診斷器的時候,有一種出現了相似無限遞歸的狀況。java

  • 問題3解決方案:
    • 首先,我從根上查找錯誤,觀察指針類的getRootElement()操做,運用的是泛型,應該是能夠轉爲String型輸出的。
    • 而後,考慮背痛診斷器的測試類和DecisionTree類有無問題。由於是書上代碼,因此我又和書上的代碼校對了一遍,代碼沒有錯誤。
    • 開始代碼調試,DecisionTree expert = new DecisionTree("D:\\IdeaProjects\\GK20172301_JavaProgramming\\src\\week6\\input.txt");操做應該是沒有問題的。
    • 最後發現了問題出在返回樹的字根上面。
    • 我當時寫了兩個關於返回字根的方法,可是最後發現都是有錯誤的。
    • 首先是返回右邊子樹的這個,陷入了無限遞歸的狀況。原本我是想仿照,構造二叉樹的第三個方法,參數是元素,左子樹,右子樹。
    • 而返回左子樹的錯誤問題就是不能轉換。這裏咱們不該該new 一個新的二叉樹出來。這樣就和定義的根沒有了關係,因此就沒法調用到子樹,也就是一個沒有孩子的新的對象。程序也就會終止。
    • 因此,最後的修改結果應該是定義兩個全局變量,leftright,同時在構造方法裏定義this.left = left;,這樣,在getLeft()中就能夠直接調用left 了。

代碼託管

上週考試錯題總結

上週無錯題,優秀!node

結對及互評

點評過的同窗博客和代碼

  • 上週博客互評狀況
    • 20172304
    • 段志軒同窗的博客一直是在進步的,教材內容總結越來充實,不是之前的寥寥幾筆帶過。感覺也很深入,爲建設中國特點社會主義而奮鬥。博客格式錯題怎麼寫了兩個?
    • 20172328
    • 李馨雨同窗的博客一直是很優秀的。內容和問題都有本身的看法和想法。給了本身獨立思考的空間。雖然咱們小組三我的會討論問題,可是這並不影響咱們我的思惟的發散。

其餘

這周的代碼很複雜,再也不是單單的一個類幾個方法。對於代碼的理解和實現上面仍是有所不足的。對於背痛代碼的錯誤,通過兩三個小時的調試也沒有找到根本緣由。
對於上學期的迭代和遞歸知識也有所忘記,應該及時溫習。對於代碼要保持高度的緊張。git

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/0 1/1 10/10
第二週 610/610 1/2 20/30
第三週 593/1230 1/3 18/48
第四周 2011/3241 2/5 30/78
第五週 956/4197 1/6 22/100
第六週 2294/6491 2/6 20/120

參考資料

相關文章
相關標籤/搜索