2018-2019-20172329 《Java軟件結構與數據結構》第六週學習總結

2018-2019-20172329 《Java軟件結構與數據結構》第六週學習總結

學無止境,但願本身能夠堅持下去,就算本身有太多的事情也不但願本身落下學習,也但願本身能夠活成本身想要的樣子!!加油吧!❤️php

教材學習內容總結

《Java軟件結構與數據結構》第十章-樹

1、概述html

  • 一、什麼是樹:樹是一種非線性結構,其中的元素被組織成一個層次結構。java

  • 二、樹的組成部分:樹由一個包含結點和邊的集構成,其中的元素被存儲在這些結點中,邊則將一個結點和另個結點鏈接起來。每一結點都位於該樹層次中的某些特定層上。樹的根就是那個位於該樹頂層的惟一結點。(注:一棵樹只有一個根結點。)node

  • 三、位於樹中叫底層的結點是上一層結點的孩子。git

  • 四、一個結點只有一個雙親,可是一個結點能夠有多個孩子。web

  • 五、同一雙親的兩個結點稱爲兄弟。
    算法

  • 六、根結點是樹中惟一一個沒有雙親的結點。沒有任何孩子的結點稱爲葉子。一個至少有一個孩其實自某一特定結點的路徑能夠子的非根結點稱爲一個內部結點。數組

  • 七、沿着起始自某一特定結點的路徑能夠到達的結點是該結點的子孫。數據結構

  • 八、結點的層也就是從根結點到該結點的長度。經過計算從根到該結點所必須越過的邊數目,就能夠肯定其路徑長度。
    函數

2、樹的分類

  • 一、對結點所含有的孩子數目無限制的樹稱爲廣義樹。

  • 二、咱們將每一結點限制爲不超過n個孩子的樹稱爲一顆n元樹。

  • 三、結點最多具備兩個孩子的樹稱爲二叉樹。(注:含有m個元素的平衡n元樹具備的高度爲lognm。所以一顆含有n個結點的平衡二叉樹具備的高度爲log2m)

  • 四、徹底樹:若是某樹是平衡的,且底層全部葉子都位於樹的左邊,則認爲該樹是徹底的。(注:徹底二叉樹在每一個k層上都具備2^k個結點,最後一層除外,在最後一層中的結點必須是最左邊的結點。)
  • 五、滿樹:若是一顆n元的全部的葉子都位於同一層且每一結點要麼是一片葉子要麼正好是具備n個孩子,則稱爲此樹是滿的。

2、實現樹的策略

  • 一、樹的數組實現之計算策略:

    • 一種策略試試用數組來進行存儲一棵樹:對於任何儲存在數組位置n處的元素而言,該元素的左孩子將存儲在位置(2✖️n➕1)處,該元素的右孩子則存儲在位置(2✖️(n➕1))處。
  • 二、樹的數組實現之模擬連接策略

    • 模擬了操做系統管理內存的方式。按照先來先服務的基準連續分配數組位置,而不是經過其在樹中的定位將數元素指派到數組位置上。

    • 模擬連接策略容許連續分配數組位置而不用考慮該樹的徹底性。
  • 三、樹的分析

    • (1)樹是實現其餘集合的有用並且有效的方式。

    • (2)通常而言,一顆含有m個元素的平衡n元樹具備的高度爲lognm。

3、樹的遍歷

  • 一、前序遍歷(preorder traversal)

    • (1)順序:從根結點開始,訪問每一結點機及其孩子。

    • (2)圖解:

  • 二、中序遍歷(inorder traversal)

    • (1)順序:從根結點開始,訪問結點的左孩子,而後是該結點,再而後是任何剩餘結點。

    • (2)圖解:

  • 三、後序遍歷(postorder traversal)

    • (1)從根結點開始,訪問結點的孩子,而後是該結點。

    • (2)圖解:

  • 四、層序遍歷(lever-order traversal)

    • (1)從根結點開始,訪問每一層全部的結點,一次一層。

    • (2)圖解:

4、二叉樹

  • 一、ADT:
操做 描述
getRoot 返回指向二叉樹根的引用
isEmpty 斷定該樹是否爲空
size 斷定樹中數量
contains 斷定指針目標是否在該樹中
find 若是找到該指定元素,則返回指向其的引用
toString 返回樹的字符串表示
iteratorInOrder 爲樹的中序遍歷返回一個迭代器
iteratorPreOrder 爲樹的前序遍歷返回一個迭代器
iteratorPostOrder 爲樹的後序遍歷返回一個迭代器
iteratorLeverOrder 爲樹的層序遍歷返回一個迭代器
  • 二、用鏈表實現二叉樹

    • (1)注:每一個構造函數必須具備root和count屬性。
  • 三、二叉樹的性質:
    • (1)性質1:在二叉樹的第 i 層上至多有 2^(i-1)個結點 (i >=1)

    • (2)性質2:深度爲 k 的二叉樹至多有2^k -1個結點(k>=1)

    • (3)性質3:對任何一棵二叉樹 T ,若是其終端結點數位n0,度爲2的結點數位n2,則n0=n2+1。

注:

(1) n = n0 + n1 + n2 (結點總數 等於 度爲0 加 度爲1 加 度爲2)

(2) n = n0 + 2*n2 +1(n = 分支總數+1 ;分支總數 = n1+n2 (分支是由度爲1,度爲2的結點射出的))

(3)-(1)得: n0 = n2 + 1

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

  • 問題1:在書中有這樣一句話:

最後一層除外,在最後一層中的結點必須是最左邊的結點。

一開始我並無特別理解這個意思是什麼,由於個人第一意識就是我以爲最後一層都除外了,還提最後一層作什麼?

  • 問題1解決方案:
    在昨天聽了老師講的課之後就知道他所說的是倒數第二層的結點必須是最左邊的結點,這裏也就引進了平衡樹的概念。
    那什麼是平衡樹呢?
    一、平衡樹:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,而且左右兩個子樹都是一棵平衡二叉樹。
    二、性質:最小二叉平衡樹的節點的公式以下 F(n)=F(n-1)+F(n-2)+1

  • 問題2:在學習使用二叉樹:表達式樹的時候,有這樣一段代碼讓我非常糾結:
public boolean isOperator() 
    {
        return (termType == 1);
    }

它的實如今下面

if (temp.isOperator())
            {
                operand1 = evaluateNode(root.getLeft());
                operand2 = evaluateNode(root.getRight());
                result = computeTerm(temp.getOperator(), operand1, operand2);
            }
            else
                result = temp.getValue();
        }

就是temp究竟是一個什麼類型的值,它如何左右與1和其餘之間字符?

  • 問題2解決方法:
    對於我本身是這樣理解的:首先temp.isOperator()這句的做用就是在判斷temp是不是一個操做符,我本身以爲termType == 1只是一個媒介,不管它是不是1都無所謂,那個1只是用於判斷是否爲一個數字,假如不爲一個數字,就判斷其爲一個操做符,假如是操做數的話,就進行繼續遞歸,繼續重複。

  • 問題3:由於在學習表達式樹的時候就在如何輸出一個數存在着疑問,書本里的代碼繁瑣,讓人很難看下去,爲何有契機寫這個問題,是由於看了侯澤洋同窗的博客之後,發現了他非常仔細的寫了每一步的過程,然而我也由於當時本身代碼實現過程當中的一點問題,bug了兩遍這一段程序,也瞭解到大體(後面會寫到那個本身犯的傻瓜問題),在這裏也進行一點記錄。
  • 問題3解決方法:

(1)首先咱們從打的包中看到了咱們這個方法中用到了四個類,包括以前寫過的一個和本章須要完善的三個,以下

import chapter10.jsjf.BinaryTreeNode;
import chapter10.jsjf.LinkedBinaryTree;
import chapter6.練習題.pp6_8.ArrayUnorderedList;
import chapter6.練習題.pp6_8.UnorderedListADT;

(2)其次咱們先要了解整個輸出的過程,假如要輸出一棵樹的話,就得有它的形狀,即如何控制咱們所須要的空格,在我本身的計算中,和書中進行了統一,假如一棵樹的層數有k層的話,就是在第0層第一個元素以前有2^k個空格" ";
而後當咱們判斷輸出第0層了之後就經過1個或者2個\n進行換行,(ps:兩個會好看一點,就和書中代碼同樣),進行判斷就須要咱們將元素和字符分別存入兩個鏈表中,由於在我bug的時候發現一個問題,就是常常作的一個操做就是將鏈表進行頭刪,返回頭刪的值,這一操做爲的是返回刪除的值進行比較,選擇是否進入判斷語句。而後換行之後,進行一樣的空格,假如遇到元素就要開始進行輸出,轉至(3)。進行新的空格計算,也就是2^(k-1),這個空格間距就是兩個元素之間的空格數目。重複上述過程。

countNodes = countNodes + 1;
            current = nodes.removeFirst();
            currentLevel = levelList.removeFirst();
            if (currentLevel > previousLevel)
            {
                result = result + "\n\n";
                previousLevel = currentLevel;
                for (int j = 0; j < ((Math.pow(2, (printDepth - currentLevel))) - 1); j++)
                    result = result + " ";
            }
            else
            {
                for (int i = 0; i < ((Math.pow(2, (printDepth - currentLevel + 1)) - 1)) ; i++) 
                {
                    result = result + " ";
                }
            }

(3)輸出元素,包括空格和換行符咱們都用一個result進行保存,之後再轉至(2)結尾。

f (current != null)
            {
                result = result + (current.getElement()).toString();
                nodes.addToRear(current.getLeft());
                levelList.addToRear(currentLevel + 1);
                nodes.addToRear(current.getRight());
                levelList.addToRear(currentLevel + 1);
            }
            else {
                nodes.addToRear(null);
                levelList.addToRear(currentLevel + 1);
                nodes.addToRear(null);
                levelList.addToRear(currentLevel + 1);
                result = result + " ";
            }

        }

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

  • 問題1:在輸出表達式樹的時候,2和1的位置老是跑偏

    我可能花了3個小時一直bug找問題,可是就是找不到

  • 問題1解決:
    我忽然意識到可能本身以前寫的添加方法不能用或者有錯,就回去看了一眼,果然不出我所料。。
    ps:以前寫的大體是這樣的:
    就是用了一個while循環,找到最後一個添加進去,最後發現,本身有毒,有個rear不用,老是想着找最後一個,確定是鏈表敲多了,本身都發現本身被鏈表已經深深的洗腦🤮🤮🤮
    更改之後:

代碼連接

上週考試錯題總結

  • 錯題1:
    There are four basic methods for traversing a tree: preorder, inorder, postorder, and level-order.
    A .Top down, bottom up, inorder, and postorder
    B .Top down, inorder, postorder, and level-order
    C .Bottom up, preorder, in order, and postorder
    D .preorder, inorder, postorder, and level-order

    正確答案: D 個人答案: B

錯因:雖然答案已經顯示出來了,可是仍是作錯了,我當時對這個題的理解就是去想着那個遍歷順序的方向了,實則沒有想到還能把答案寫出來。

  • 錯題2:
    ___________ traversal means visit the nodes at each level, one level at at time, starting with the root.
    A .preorder
    B .postorder
    C .inorder
    D .level-order

    正確答案: D 個人答案: A

錯因:我剛剛思考了一下我爲何選的是A,多是我當時用了翻譯,翻譯的讓我撒懶,不再相信谷歌翻譯了。

結對及互評

  • 本週結對學習狀況
  • 博客中值得學習的或問題:
    • 內容詳略得當;
    • 代碼調試環節比較詳細;
  • 基於評分標準,我給本博客打分:5分。得分狀況以下:
  1. 正確使用Markdown語法(加1分):
  2. 模板中的要素齊全(加1分)
  3. 教材學習中的問題和解決過程, 一個問題加1分
  4. 代碼調試中的問題和解決過程, 一個問題加1分

  • 博客中值得學習的或問題:
    • 內容詳略得當;
    • 代碼調試環節比較詳細;
  • 基於評分標準,我給本博客打分:9分。得分狀況以下:
  1. 正確使用Markdown語法(加1分):
  2. 模板中的要素齊全(加1分)
  3. 教材學習中的問題和解決過程, 一個問題加1分
  4. 代碼調試中的問題和解決過程, 一個問題加1分

感悟

本週應該是我以爲全班以爲學習Java第一次不少人都說不懂,因此難說明其重要性,樹,的確是一個樹,給咱們帶來了無窮無盡的生機,天天晚上在熬夜寫代碼的時候,就以爲本身真的在納涼,都快被凍死了。
雖然本週過的實在不易,可是終究咱們仍是把它摳出來了,雖然仍是有一些問題,可是總比一竅不通好,我看到了如今班裏呈現出的學習氛圍並無那麼強烈了,你們有些人都開始應付做業,應付老師,我以爲實則不應,如今享受之後要享受的時光,之後終究是要還回來的,因此,你們加油,共勉!

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積)
目標 5000行 30篇 400小時
第一週 0/0 1/1 6/6
第二週 1313/1313 1/2 20/26
第三週 901/2214 1/3 20/46
第四周 3635/5849 2/4 20/66
第五週 1525/7374 1/5 20/86
第六週 1542/8869 2/5 25/111

參考資料

藍墨雲班課
Java程序設計
數據結構之平衡樹(Treap)
二叉樹的4種遍歷方法圖解
二叉樹遍歷的遞歸、非遞歸算法(Java實現)

相關文章
相關標籤/搜索