DS博客做業05--樹

1.思惟導圖及學習體會

1思惟導圖

2.談談你對樹結構的認識及學習體會。

  • 1. 樹形結構屬於非線性結構,經常使用的樹形結構有樹和二叉樹。樹是由n(n>=1)個有限節點組成一個具備層次關係的集合。樹的基本術語有:結點的度與樹的度;分支節點與葉子結點;路徑與路徑長度;孩子結點、雙親結點和兄弟結點;結點層次和樹的高度等等。樹有多種類型,可分爲二叉樹和哈夫曼樹等,其中二叉樹又可分爲徹底二叉樹和滿二叉樹。 在樹中主要學習了二叉樹和哈夫曼樹這種樹。
  • 2. 二叉樹:二叉樹是一種特殊的樹。二叉樹的特色是每一個結點最多有兩個兒子。二叉樹的存儲結構能夠有順序存儲結構和連式存儲結構。能夠經過二叉樹的疏密以及題目要求等來決定樹的存儲結構。二叉樹遍歷的方法有先序遍歷、中序遍歷、後序遍歷與層次遍歷四種方法。不論在樹的創建或其餘基本運算中基本是要運用到遞歸,代碼量少,可是理解起來不容易,並且錯誤地方不容易調試看出來。
  • 3. 樹的學習仍是學的更懵逼了,特別是一開始遞歸部分很差理解,並且這章節須要記住的知識點不少,孩子節點、兄弟節點、滿二叉樹、徹底二叉樹等等一堆東西,我以爲我腦子已經不夠用了,PTA上的題目以及不友好了,特別是表達式還有一堆的編程題,還有須要遞歸的地方,以及此次大做業,能寫出來感受真是厲害了,這學期真是不容易啊,學的要死要活的...轉專業來不及了都

2.PTA實驗做業

2.1.題目1:6-4 jmu-ds-表達式樹

輸入一行中綴表達式,轉換一顆二叉表達式樹,並求解.
表達式只包含+,-,*,/,(,)運算符,操做數只有一位,且爲整數(有興趣同窗能夠考慮負數小數,兩位數作法)。按照先括號,再乘除,後加減的規則構造二叉樹。
如圖所示是"1+(2+3)*2-4/5"代數表達式對應二叉樹,用對應的二叉樹計算表達式的值。 轉換二叉樹以下:

2.1.1設計思路(僞代碼)

void InitExpTree(BTree &T, string str) //建表達式的二叉樹
創建字符棧op和樹根棧node
建立樹結點p等於NULL,a,b
定義i=0表示循環變量 定義字符來存判斷兩符號的優先關係的函數返回的符號
while 表達式str未結束
    if str[i] 是數字字符 then
       建立樹節點p
        將結點存入樹棧node中 node.push(p)
     else if str[i]是運算符 then
         if op.empty() then op.push(str[i])   //若是棧空 則將字符存進去
         else
             f = Precede(op.top(), str[i])   //判斷兩符號的優先關係
         switch f
                case:'>' 
                        從樹棧node出棧兩個結點存入a,b中
                        調用CreateExpTree函數建立數二叉樹p併入棧
                        i--
                        break
                case '<':op.push(str[i]); break;  //優先級比棧頂元素高
        case '=':op.pop(); break; 
end while    

while 運算符棧op中不爲空且棧node也不爲空   
              從樹棧node出棧兩個結點存入a,b中
              調用CreateExpTree函數建立數二叉樹p併入棧          

end while



double EvaluateExTree(BTree T)
定義浮點數sum,b,m
創建double類型的棧 num表示將每一次計算結果存進去以及取出來
創建字符棧 s表示存入的數據有運算符有數
創建樹類型的棧 node表示每次取數的結點
while T
     將每一個結點的數據一個個存入s,以及將結點T存入node中
end while
while s不爲空
    if s的棧頂元素爲數字 then
      將字符轉化爲數存入num中
    else //爲運算符時候
       sum=num的棧頂元素
        num去棧頂元素
        b=num的棧頂元素
        num去棧頂元素
        switch s的棧頂元素
            case '+':sum += b; break;
        case '-':sum -= b; break;
        case '*':sum *= b; break;
            case '/':
         if b等於0  
                輸出divide 0 error!\n
                關閉程序
            else sum /= b;
            end if 
            break    
    s.pop();
    num.push(sum);      
返回sum

2.1.2代碼截圖



2.1.3本題PTA提交列表說明。

  • Q1:一開始提交時候是爲多種錯誤,裏面有段錯誤有答案錯誤
  • A1:當我在判斷了棧頂優先級高的時候,搞錯了要從node中彈出兩個根結點出來,我只彈出一個致使出現錯誤,主要仍是老師給咱們講過了,還給了咱們建樹的ppt的僞代碼,而後纔會打...
  • Q2:後來只對了五分的狀況,是隻對了除0錯誤這個測試點,至於其餘兩個主要測試點都沒過
  • A2:這個改了特別久,改了好幾天,一直沒發現錯誤,後來發現,原來在創建這棵樹的時候,判斷符號優先級別時,當Precede返回大於號時候,還要i減一,否則在後面i在加一可能不能一直判斷棧頂元素與當前元素的優先級誰高

2.2.題目1:7-4 jmu-ds-二叉樹葉子結點帶權路徑長度和

二叉樹葉子結點的帶權路徑長度指:葉子結點的權重路徑長度。本題要求算出二叉樹全部葉子結點的帶權路徑長度和。 以下面的二叉樹:

2.2.1設計思路(僞代碼)

主要說建樹函數和計算權值的函數
BiTree create(string str, int n) 
創建新的樹節點 BT
if str[n] 等於字符# 返回NULL end if
if n>str.size() - 1 返回NULL end if
BT->data = str[n];                                                                                       
BT->lchild = create(str, 2 * n); //遞歸建樹
BT->rchild= create(str, 2 * n+1);
返回 BT;


void GetWPL(BiTree bt,int h,int&wpl)
if bt等於NULL 返回 
end if 
if bt左右孩子不空  
    wpl=wpl+(bt->data-'0')*h;
end if 
    GetWPL(bt->lchild,h+1,wpl);
    GetWPL(bt->rchild,h+1,wpl);

2.2.2代碼截圖

2.2.3本題PTA提交列表說明。

  • Q1:第一次和第二次的只有五分的測試點過了,而後也百度過了也是沒出來
  • A1:直到正確答案出來我再看一下原來代碼,發現錯誤的是在計算權值的函數中,再對左右子樹的搜索中,我是將對左右子樹的遍歷放在判斷是否爲葉子結點裏面,致使其實沒對整顆二叉樹進行遍歷
  • Q2:再第三四次的提交中,仍是隻有五分,後來上課看了老師的作題後發現了錯誤
  • A2:在傳參時候應該先傳進去0,而不是傳進去1,若是是1的話會致使層數多1,而致使最後結果錯誤
  • Q3:在其中還有就是有時devc有跳錯
  • A3:遞歸口設置的不對,致使最後到了空時候還進行操做致使出錯
    ***node

    2.3.題目1:7-2 根據後序和中序遍歷輸出先序遍歷

本題要求根據給定的一棵二叉樹的後序遍歷和中序遍歷結果,輸出該樹的先序遍歷結果。

2.3.1設計思路(僞代碼)

#include<iostream>
using namespace std;
int in[31], post[31];
typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;



BiTree Build(int *in, int *post, int n)//第一個參數是中序序列的起始位置,第二個參數是後序序列的起始位置,n是長度 

    定義len, *p
    if n <= 0 then//若是長度小於等於0,直接返回便可 
        return NULL
        end if 
    p = in;
    for pto in+n  //少打了一個+n
        if  *p == *(post + n - 1) then break
                end if
         enf for
    創建新結點T
    T->data = *p
    len = p - in;
    T->lchild = Build(in, post, len);
    T->rchild = Build(p + 1, post + len, n - len - 1);
    返回T



void PreOrder(BiTree T)

    if T不爲空 then 
        輸出 T->data;
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    end if 
    return




int main()

    定義 n, i=0分別表示數組長度和循環變量;
    BiTree T;//只須要定義,不須要賦值->[BiTree T = new BiTNode;] 
    輸入 n
    for i to n do 
        輸入 post[i]
         end for
    for i to n do 
        輸入 in[i]
         end for
    T = Build(in, post, n)
    輸出"Preorder:"
    PreOrder(T)
    return 0

2.3.2代碼截圖

2.3.3本題PTA提交列表說明。

  • Q1:多種錯誤中有答案錯誤還有格式錯誤
  • A1:格式錯誤能夠解決,那個答案錯誤,一開始覺得應該將p賦值放在循環外,但這個沒影響啊,後來是循環條件錯了,忘了in是用指針來的,應該p小於in+n
  • Q2:再改了循環條件後再次提交就過了一個測試點
  • A2:對於形參n,再建立右子樹時候錯誤,原本是寫n-len,後來調試一點點畫圖一點點看時候,發現應該還要再減一才正確

三、閱讀代碼

3.1 題目 :判斷一棵樹是不是另外一棵樹的子樹


3.2 解題思路

  • 1.樹的後序遍歷的最後一個數必定是樹的根節點,因此根據後序和中序利用遞歸建好樹
  • 2.再用隊列層次輸出ios

    3.3 代碼截圖



3.4 學習體會

  • 1. 他經過中序和後序來建樹和我不太同樣,看起來比我方便多了,還多了個形參
  • 2.在層次輸出那一塊的代碼,我在打pta的那道題時候,打不出來,而後他用了隊列的方法,這個一開始是沒想到的,用隊列作的確更快,原本我想用遞歸的
相關文章
相關標籤/搜索