20172305 2018-2019-1 《Java軟件結構與數據結構》第七週學習總結

20172305 2018-2019-1 《Java軟件結構與數據結構》第七週學習總結

教材學習內容總結

本週內容主要爲書第十一章內容:

  • 二叉查找樹(附加屬性的二叉樹)
    • 二叉查找樹是對樹中的每一個結點,其左結點都要小於其父結點,而父結點又小於或等於其右結點。
    • 二叉查找樹的定義是二叉樹定義的擴展。
  • LinkedBinarySearchTree類的相關方法:
    • addElement操做(相似有序列表的添加方法,元素必須是Comparable,不是的話會拋出NoComparableElementException異常)html

      • 若是樹爲空,則新元素成爲根結點
      • 若是樹非空,則新元素會與樹根,元素進行比較。
    • removeElement操做(相似列表的刪除指定元素的方法,找不到給定目標元素則拋出ElementNotFoundException異常)java

      • 在樹中找不到給定目標元素時,會拋出ElementNotFoundException異常。
      • 在樹中找到給定目標元素時,若是被刪除結點沒有子結點,則替代元素爲null;若是被刪除結點只有一個結點,則替代元素爲該結點;若是被刪除結點有兩個子結點,則替代元素用中序查找。
    • removeAllOccurrences操做(刪除指定元素的全部存在,若是找不到給定目標元素則拋出ElementNotFoundException異常,若是找到元素不是Comparable,則拋出ClassCastException異常)git

      • 調用LinkedBinaryTree類的contains方法肯定樹中是否含有目標元素。
      • 調用removeElement來實現刪除元素,並確保當樹中沒有該元素的時候拋出異常。(而後捕獲異常不輸出任何內容)
    • removeMin操做(查找最小元素 + 刪除目標元素)數據結構

      • 若是樹根沒有左子結點,則樹根就是最小元素,而樹根的右子結點將成爲新的根結點。
      • 若是樹的最左側結點是葉結點,則葉結點就是最小元素,這是隻需定義父節點的左子結點爲null。
      • 若是樹的最左側結點是一個內部節點,則須要設置其父節點的左結點引用指向這個將刪除結點的右結點。
  • 二叉查找樹的各操做的時間複雜度分析學習

  • 蛻化樹(相似鏈表,但比鏈表的效率低,每個結點要附帶額外的開銷)3d

  • 平衡二叉查找樹,自樹根而下的路徑最大長度必須不超過log2n,並且字樹根而下的路徑最小長度必須不小於log2n-1。
    • 右旋(左結點繞着其父結點向右旋轉):根結點的左子結點成爲新的樹根,原根結點元素成爲根節點的右子結點元素,原樹根的左子結點的右子結點成爲原樹根的新的左子結點。
    • 左旋(右結點繞着其父結點向左旋轉):根結點的右子結點成爲新的樹根,原根結點元素成爲根節點的左子結點元素,原樹根的右子結點的左子結點成爲原樹根的新的右子結點。
    • 右左旋(先讓樹根右結點的左子結點,繞着樹根的右結點進行一次右旋,而後再讓所得樹根右結點繞着樹根進行一次左旋)
    • 左右旋(先讓樹根左結點的右子結點,繞着樹根的左結點進行一次左旋,而後再讓所得樹根左結點繞着樹根進行一次右旋)
  • 平衡二叉查找樹--AVL樹使用每一個結點的平衡因子來保持二叉查找樹平衡的策略。
    • 平衡因子:某結點的右子樹的高度減去左子樹的高度。
    • 平衡因子大於1或是小於-1則須要以該結點爲樹根的子樹進行從新平衡。
  • 平衡二叉查找樹--紅黑樹(非嚴格意義上的平衡二叉樹)使用與每一個結點相關顏色(紅色或是黑色)來保持二叉查找樹平衡的策略。調試

    • 紅黑樹知足的性質:
    • (1.)每一個結點或是紅色或是黑色
    • (2.)根結點是黑色的
    • (3.)每一個葉結點(爲空)都是黑色的
    • (4.)若是一個結點是紅色,則他的兩個子結點都是黑色
    • (5.)對每一個結點,從該結點到子孫結點的全部路徑上包含相同數目的黑結點

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

  • 問題1:紅黑樹的添加刪除方法?
  • 問題1解決方案:
    • 添加元素的判斷條件:
    • 添加元素的父節點是添加元素的祖父節點的左結點:htm

      • 狀況一添加結點的叔叔是紅色的,針對這種狀況,咱們將雙親結點和叔叔結點爲黑色,而後將祖父結點染成紅色,再以祖父結點設爲當前結點實現遞歸向上,直至到根結點爲止。
      • 狀況二添加結點的叔叔是黑色的,添加結點是右結點。這種狀況須要先旋轉到第三種狀況,即以添加結點的父結點爲支點進行左旋達到第三種狀況,再按照第三種狀況進行。
      • 狀況而添加結點的叔叔是黑色的,添加結點是左結點。這種狀況須要將雙親結點染爲黑色,祖父結點染爲紅色,以祖父結點爲支點進行左旋。
    • 添加結點的父結點是添加元素的祖父結點的右結點:對象

      • 第一種狀況 是添加結點的叔叔是紅色的,這種狀況和上一種大前提下的狀況一致,將雙親結點和叔叔結點染爲黑色,而後再將祖父結點染爲紅色,將祖父結點視爲新的結點實現遞歸,直至傳到根節點。
      • 第二種狀況 是添加結點的叔叔是黑色的,並且添加結點是左子結點,這種狀況須要先旋轉到第三種狀況,即以添加結點的父結點爲支點進行右旋達到第三種狀況,再按照第三種狀況進行。
      • 第三種狀況 是添加結點的叔叔是黑色的,並且添加結點是右子結點。這種狀況須要將雙親結點染爲黑色,祖父結點染爲紅色,以祖父結點爲支點進行左旋。
    • 刪除操做(刪除操做理解淺談)blog

      • 第一種狀況 刪除結點的兄弟是紅色的,刪除結點的兄弟是紅色的,那麼父親結點是黑色的,這種狀況就須要改變兩個結點的顏色,而後以父結點爲支點進行左旋,達到第二種狀況或是第三種狀況或是第四種狀況
      • 第二種狀況 刪除結點的兄弟是黑色的,並且兄弟結點的兩個結點都是黑色的
      • 第三種狀況 刪除結點的兄弟是黑色的,並且兄弟結點的左子結點爲紅色,右子結點爲黑色,針對這種狀況,咱們先將兄弟結點和左子結點的顏色交換,即變色後以兄弟結點爲支點進行右旋達到第四種狀況
      • 第四種狀況 刪除結點的兄弟結點是黑色的,並且兄弟結點的右結點是紅色

代碼學習中的問題和解決過程

  • 問題1:PP11.10的add操做如何實現遞歸?
  • 問題1的解決方案:遇到這道題目,第一感受就是很迷,不知從何下手,並且說的add操做在二叉查找樹的鏈表實現中也叫addElement操做。並且addElement的操做用到了遞歸,一個方法調用另外一個遞歸的方法,因此我在此基礎上進行了兩個方法的結合,常使用一個遞歸的方法來實現。其實addElement操做,之因此分紅兩個方法的緣由是調用遞歸的方法進行着根結點是否爲空,空的話就實現根結點等於添加元素;以及判斷元素是不是Comparable類型,而遞歸的方法是要進行添加元素到某一個結點的左側或是右側。從二者的實現差別來看,遞歸的方法須要兩個參數實現,而調用遞歸的方法只須要一個參數,把參數的內容插入到樹上就行。可是若是把二者結合把調用遞歸的方法也改爲兩個參數的,嘗試了一下結果是出現這種排不了序的結果。只是在上一步產生的樹的總體進行一個比較,而不是針對每個結點的元素比較。

    • 錯誤示例:
  • 問題2:在無返回值的條件下語句有return的做用?
  • 問題2的解決方案:return的使用一直在存在返回值條件下使用,可是從未在無返回值條件下使用。若是return後面不接內容的話,就會結束該方法並不會輸出任何內容的。

    • (1.)return語句:是指結束該方法,繼續執行方法後的語句。
    • (2.)break語句:是指在循環中直接退出循環語句(for,while,do-while,foreach),break以後的循環體裏面的語句也執行。
    • (3.)continue語句:是指在循環中中斷該次循環語句(for,while,do-while,foreach),本次循環體中的continue以後語句不執行,直接跳到下次循環。
  • 問題3:removeMax、findMax、findMin如何編寫?

    • removeMax:刪除樹中的最大元素
    • findMax:返回樹中最小元素的引用
    • findMin:返回樹中最大元素的引用
  • 問題3解決方案:書中給出了刪除最小元素的方法,根據提供的代碼以及二叉查找樹的了內部結構,最小元素在根結點的左側查找,那麼最大元素則在根結點的右側查找。具體分析一下刪除最小元素,根據二叉查找樹的結構能夠發如今查找最小元素的時候,若是根結點的左側沒有子結點,那麼根結點即爲要刪除的最小結點,根結點的右側子節點爲新的根結點。若是根結點的左側有子結點,那麼遍歷左側找到最小的結點,可是直接刪除給節點是不行的,要考慮到刪除的該結點的時候有可能存在其右子結點,這是要把右子結點移到刪除結點的位置。因此,刪除最大元素,也分兩種狀況,在根結點的右側沒有子結點,那麼根結點即爲要刪除的最大元素,根結點的左側元素即爲根結點。若是根結點的右側右子結點,那麼遍歷右側找到最大的結點,把該結點的左子結點替代到刪除的位置。而查找的方法只需在省略刪除結點的子結點替代刪除位置的相關代碼就行。

  • 問題4:AVL樹的左旋、右旋、左右旋、右左旋的方法實現?
  • 問題4解決方案:AVL樹的旋轉是利用各結點的平衡因子來肯定是否平衡,若是不平衡根據各結點的平衡因子的大小進行計算。

    • 左旋:根結點右子結點成爲新的根結點,右子結點的左子結點成爲原根節點的右子結點。
    • 右旋:根結點左子結點成爲新的根結點,左子結點的右子結點成爲原根結點的左子結點。
    • 左右旋:以根結點的左子結點爲新的根結點,進行左旋(根結點的新左子結點爲原左子結點的右子結點),而後在以原根結點進行右旋。
    • 右左旋:以根結點的右子結點爲新的根結點,進行右旋(根結點的新右子結點爲原右子結點的左子結點),而後在以原根結點進行左旋。
  • 問題5:AVL樹的添加和刪除方法如何編寫?
  • 問題5解決方案:
    • addElement操做:在插入元素的以前,先判斷元素是不是Comaprable類型以及判斷插入的結點是否爲空,若是爲空的話就構造一個新的AVL樹(左右子結點均爲null),而後開始個插入結點位置進行判斷。

      • 若是比目標結點小的話,進行結點的左側插入,經過以目標結點的左子結點爲新的根結點進行判斷實現遞歸操做。由於咱們已經肯定是在左側添加元素,那麼整棵樹的左側高度必然要大於右側高度,可是咱們不肯定差值是多少,可是差值也只能爲-2或-1或0(右側高度減左側高度)。因此根據差值進行判斷,若是相差爲-2,那麼添加元素後須要進行平衡。經過判斷新加元素在左側樹的左側仍是右側,若是在左側直接進行一次右旋;在右側進行一次左右旋。
      • 若是比目標結點大或是相等的話,進行結點的右側插入,經過以目標結點的右子結點爲新的根結點進行判斷實現遞歸操做。在肯定在右側添加以後,右側高度會比左側高度要大,可是差值也只能爲2或1或0(右側高度減左側高度)。因此根據差值進行判斷,若是相差爲2,那麼添加元素後須要進行平衡。經過判斷新加元素在右側樹的左側仍是右側,若是在左側直接進行一次右左旋;在右側進行一次左旋。
    • removeElement操做:在刪除元素以前,先判斷結點是否爲空,在不爲空的前提下進行刪除操做。

      • 若是刪除元素在根結點的左側,經過以根結點的左子結點爲新的根結點進行判斷實現遞歸操做。由於在刪除元素以前,整棵樹都是平衡的,因此每一個結點的平衡因子都是0或1或-1,而在刪除元素以後,致使整棵樹不平衡,可是也只會出現不平衡狀態下的平衡因子存在2(右側高度減左側高度),那麼就至關於根結點的右子結點的添加一個元素,經過比較右子結點兩側高度來判斷,若是左側高於右側就進行右左旋,若是右側高於或等於左側就進行左旋。
      • 若是刪除元素在根結點的右側,經過以根結點的右子結點爲新的根結點進行判斷實現遞歸操做。由於在刪除元素以前,整棵樹都是平衡的,因此每一個結點的平衡因子都是0或1或-1,而在刪除元素以後,致使整棵樹不平衡,可是也只會出現不平衡狀態下的平衡因子存在-2(右側高度減左側高度),那麼就至關於根結點的左子結點的添加一個元素,經過比較左子結點兩側高度來判斷,若是左側高於右側就進行右旋,若是右側高於或等於左側就進行左右旋。
      • 若是刪除元素是根結點,那麼若是根結點的左側右側均不爲空的話,若是左子樹高於右子樹那麼從左子樹中找尋最大元素;若是右子樹高於左子樹那麼從右子樹找尋最小的元素。這種方法避免旋轉,由於不管是在左子樹內找最大的仍是在右子樹中找尋最小元素替代,這兩種元素的都只是葉結點,在未刪除以前已經平衡好,平衡因子只能爲0,因此替代以後也爲平衡樹。
      • 若是刪除元素是根結點,那麼若是根結點沒有右子結點,那麼左子結點成爲新的左結點;那麼若是根結點沒有左子結點,那麼右子結點成爲新的根結點。

代碼託管

上週考試錯題總結

上週無錯題...

結對與互評

點評(王禹涵)

  • 博客中值得學習的或問題:
    • 背景圖很好看,仍是截圖內容看得不清晰,建議換個背景圖。
  • 代碼中值得學習的或問題:
    • 代碼圖片也是看的不清晰,下次嘗試用電腦作出的框圖來嘗試。
  • 基於評分標準,我給本博客打分:8分。
    • 得分狀況以下:
    • 正確使用Markdown語法(加1分)
    • 模板中的要素齊全(加1分)
    • 教材學習中的問題和解決過程, 三個問題加3分
    • 代碼調試中的問題和解決過程, 一個問題加1分
    • 感想,體會不假大空的加1分
    • 點評認真,能指出博客和代碼中的問題的加1分

點評(方藝雯)

  • 博客中值得學習的或問題:
    • 圖片特別細緻,可是針對那一大串代碼建議配一些講解,建議不要全放到代碼註釋中。
  • 代碼中值得學習的或問題:
    • 代碼問題感受像是沒有寫完整的感受。
  • 基於評分標準,我給本博客打分:8分。
  • 得分狀況以下:
    • 正確使用Markdown語法(加1分)
    • 模板中的要素齊全(加1分)
    • 教材學習中的問題和解決過程, 三個問題加3分
    • 代碼調試中的問題和解決過程, 一個問題加1分
    • 感想,體會不假大空的加1分
    • 點評認真,能指出博客和代碼中的問題的加1分

互評對象

感悟

第十一章的二叉查找樹學起來比樹還難學,欲哭無淚。二叉查找樹的添加和刪除與有序列表的添加刪除差很少,每添加一個就要判斷一次還要看平不平衡,不平衡的話還得給它弄平衡了,還有紅黑樹的方法,感受都繞暈了,特別懵,遞歸和迭代,吐血(絕望)...

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/0 1/1 15/15
第二週 703/703 1/2 20/35
第三週 762/1465 1/3 20/55
第四周 2073/3538 1/4 40/95
第五週 981/4519 2/6 40/135
第六週 1088/5607 2/8 50/185
第七週 1203/6810 1/9 50/235

參考資料

相關文章
相關標籤/搜索