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

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

教材學習內容總結

非線性數據結構——樹

  • 結點:結點分爲根節點,內部結點。根據結點分爲parent和children,結點之上爲parent,之下爲children。位於同一結點的下的結點爲sibling。
  • order(度):每一個結點所擁有的最大children數,根據此定義,較爲常見的二叉樹得以命名。
  • 分類:1.平衡樹,全部葉子位於同一層或者至少彼此相差不超過一層。2.徹底樹,在平衡的基礎上,底層全部葉子位於樹的左邊。3.滿樹,對於一個n元樹,每層葉子都是滿的,且均在同一層。html

    實現樹的方法。

  • 1.使用鏈表。
  • 由於樹的數據結構,每一個結點指向其孩子,所以使用鏈表較爲簡單。
  • 2.使用數組。
    • 根據二叉樹的特殊性質,將左孩子存在數組(2 * n - 1 ) 索引值處,右孩子在(2 * n+1))處。但問題在於,當出現非滿樹的狀況時,數組中的某些位置就必須空下以表示某parent只有一個孩子,當一個樹大量存在這種狀況時,將浪費大量的空間。
    • 模擬連接法。建立一個node型數組,使得每一個元素存儲下一個children的地址。問題,當刪除一個結點時,若是不保留原結點位置,子結點移動時將會很是麻煩。若是隻將其內部元素刪除,保留內部結點的引用關係,又會佔用空間。java

      樹的遍歷

  • 前序遍歷,中序遍歷,後序遍歷,層序遍歷
  • 前序遍歷。從根節點開始,依次遍歷至葉子處的左孩子,再依次由下至上返回由孩子。直到將整個樹遍歷完成。
  • 中序遍歷。從根結點開始。(注意,此時的從根節點開始並非說第一個也就是根節點開始,而是從根節點到最後一個最左葉結點方向)從最左葉節點開始,至其parent結點,再至其右孩子。以此爲規律,遍歷整個樹。
  • 後序遍歷。和中序遍歷相同,從最左葉結點開始,而後至其兄弟結點。再至其parent結點。以此爲規律,遞歸。
  • 層序遍歷。顧名思義,一層一層的遍歷。從根節點開始。直到最後一層。
    node

二叉樹

  • 二叉樹。一個結點最多隻有兩個孩子。
  • 二叉查找樹。左孩子始終小於雙親,而雙親始終小於等於右孩子
  • 二叉樹的性質。
    • 若根結點的層次爲1,則二叉樹第i層最多有
      2^(i-1)(i>=1)個結點。
    • 在高度爲h的二叉樹中,最多有
2^h-1

個結點git

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

  • 問題1:對平衡二叉查找樹的理解探究
  • 問題1理解:
  • 平衡樹的定義:它是一 棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,而且左右兩個子樹都是一棵平衡二叉樹。從這定義就能夠看出具備遞歸的思想。
  • 爲何須要使用二叉樹?樹做爲一種非線性結構,並不以線性方式存儲數據,這樣一來,尤爲是對於查找效率,將大大提升(從O(n)到O(logn))。但當出現一些極端例子時,樹的優點將不復存在,如圖。


此時將一個順序列表存入其中,樹變爲了右單子樹或左單子樹。問題出現了,此時的樹直接變成了列表,查找效率也從O(logn)變爲O(n)。爲了解決這個問題,咱們引入了平衡樹的概念。如此,對於以不管何種順序存入樹的元素,不至於存的太深。在各個子樹最多隻能相差一的限制下,樹的優點得以保留。算法

  • 問題2:本章內容出現許多的迭代器與迭代器方法,對迭代器的探究。
  • 問題2理解:
  • 首先明確迭代的意義是什麼。迭代是重複反饋過程的活動,其目的一般是爲了逼近所需目標或結果。每一次對過程的重複稱爲一次「迭代」,而每一次迭代獲得的結果會做爲下一次迭代的初始值。
  • 從概念上來看,迭代彷佛與遞歸十分類似,都有着重複的過程。那麼區別在哪呢?遞歸,簡單的來講,就是本身調用本身,直到到達限制條件。遞歸併非這樣,遞歸一般有一個計數器,也就是經過循環不斷進行計算,循環何時截止呢?在達到計數器時,結束循環。經過以前的代碼能夠知道,同一問題,遞歸實現的代碼十分簡潔可讀。但循環體則較爲複雜,對於一個複雜問題,短期不易理解。但遞歸在帶來代碼簡潔的同時,執行代碼時將佔用大量內存,稍有不慎會使得棧溢出,拋出異常。迭代則不會這樣。
  • 如今回到迭代器(Iterator)。內部有三個方法。hasnext,next,remove經過重寫這三個方法,使得在不破壞內部結構的狀況下,返回出內部的數據。

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

  • 問題1:對於樹中removeSubtree的方法
  • 問題1解決方案:首先,明確要求,刪除某一個右子樹,直接將其設爲null便可。問題在於,如何找到對應的右子樹。是根據對應的那個元素斷定仍是對應的結點?其實均可以,代碼以下:
if (next == null)
            return null;
        
        if (next.getElement().equals(targetElement))
            return next;
        
        BinaryTreeNode<T> temp = findNode(targetElement, next.getLeft());
        
        if (temp == null)
            temp = findNode(targetElement, next.getRight());
        
        return temp;
BinaryTreeNode<T> current = findNode(targetElement, root);
        
        if (current == null)
            throw new ElementNotFoundException("LinkedBinaryTree");
        
        return (current.getElement());

分別鎖定了對應的位置和結點。所以任意調用這兩個方法之一,便可找出相應的右子樹。從而將其刪除。刪除時,將對應結點視爲樹的根,直接將根所在的LinkedBinary樹等於null便可。數組

  • 問題2:在測試contain方法時出現了異常的問題
  • 問題2解決方案:測試以前,還出現了一段小插曲。如圖,

顯示了報錯,同時沒法執行代碼。反覆嘗試無果後,發現以前使用棧實現了一個Postfixtest,而本章也有一個使用數實現的計算後綴表達式的程序,在將其重名的更名後,重啓了幾回idea後,如願恢復了正常。個人理解是,首先idea必須保證全部程序不出錯,不然其餘程序編譯將沒法經過,同時,對於兩個同名程序,沒法判斷執行哪一個,所以選擇不執行,知道將其改變。數據結構

  • 根據拋出異常顯示的位置,發現是removeSubRighttree出了問題,



但是,拋出的是空指針異常,也就是並未找到所要刪除的結點。因此問題不在這裏。在於findnode方法,在方法體,我設置傳入了一個的LinkedBinary的參數,可是,該樹此時爲空,天然將致使其爲空指針。ide

  • 解決了這個問題,再到contain方法,又出現了問題。依舊爲空,仔細比對,發現了問題。在方法頭,從新實例化了一個LinkedBinary對象,可是,其實樹已經在以前方法肯定,從新實例化反而至關於將其清空,形成空指針的狀況。學習

    代碼託管

結對及互評

  • 博客中值得學習的或問題:
    排版精美,對於問題研究得很細緻,解答也很周全。
  • 代碼中值得學習的或問題:
    代碼寫的很規範,思路很清晰,繼續加油!

點評過的同窗博客和代碼

  • 本週結對學習狀況
  • 20172313
  • 20172332測試

    結對學習內容

  • 第十章 樹

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

  • 第一次學習非線性數據結構,對於某些知識還不是很瞭解,將繼續對這些展開學習

    學習進度條

    代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
    目標 5000行 30篇 400小時
    第一週 0/0 1/1 3/3
    第二週 409/409 1/2 5/8
    第三週 1174/1583 1/3 10/18
    第四周 1843/3426 2/5 10/28
    第五週 539/3965 2/7 20/48
    第六週 965/4936 1/8 20/68

參考資料

相關文章
相關標籤/搜索