DS博客做業05--樹

1.本週學習總結

1.思惟導圖

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

相比前面的內容,樹的學習難度加大了。樹包括孩子結點、兄弟結點、雙親結點,樹的遍歷順序有先序遍歷、中序遍歷、後序遍歷、層次遍歷。能夠根據先序遍歷和中序遍歷或中序遍歷和後序遍從來還原樹,轉換成代碼就須要找一下其中的規律。
樹中哈夫曼樹的帶權路徑長度達到最小,也叫最優二叉樹。哈夫曼樹的創建要把權值較小的結點放較下層,權值較大的結點要越靠近根結點。
樹的應用與遞歸密切相關,因此咱們要捋清遞歸的規則,知道它的執行原理,才能應用遞歸來解決問題。一級級調用,再一級級返回。

2.PTA實驗做業

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

2.1.1設計思路(僞代碼)

void InitExpTree(BTree &T,string str)  //建表達式的二叉樹
定義棧s存放數字
定義棧op存放運算符
先將‘#’進op棧
while(str[i])
{
        if str[i]是數字
              T=new BiTNode;
          T->data=str[i++];
          T的左右孩子置爲NULL
          T進棧s
        else
               調用Precede函數比較op棧頂元素與str[i]大小
                若是函數值爲'<'
                       str[i]進op棧
                若是函數值爲'='
                       op棧出棧
                若是函數值爲'>'
                       str[i]進op棧
                       T=new BiTNode;
                       op棧頂元素賦值給T->data
                       T->rchild=s.top();
                       s棧出棧
                       T->lchild=s.top();
                       s棧出棧
                       s.push(T);
                       op棧出棧
                    
}
while(op棧頂元素不是'#')  //把樹結點的關係連起來 
{
    T=new BiTNode;
    op棧頂元素賦值給T->data
    op棧出棧
    T->rchild=s.top();
    s棧出棧
    T->lchild=s.top();
        s棧出棧
    s.push(T); 
}
double EvaluateExTree(BTree T)計算表達式樹
定義a,b
if  樹T不空
      if 左右孩子都爲空
            return T->data-'0';
      a=EvaluateExTree(T->lchild)
      b=EvaluateExTree(T->rchild)
      判斷T->data
            若是是'+'
                 return a+b
            若是是'-'
                 rerurn a-b
            若是是'*'
                  return a*b
            若是是'/'
                  if  b==0
                        輸出divide 0 error!
                        退出程序
                  不然
                         return a/b

2.1.2代碼截圖(注意,截圖,截圖,截圖。不要粘貼博客上。)



2.1.3本題PTA提交列表說明。

Q1:把表達式建成樹比較有難度
A1:葉子結點都是表達式中的數字,首先遇到數字就賦值給樹結點,而後把結點進s棧。遇到運算符就比較複雜了,先要判斷運算符和op棧頂元素的大小。若該運算符大於op棧頂元素,就要先把op棧頂元素和s棧裏元素關係先建起了。小於則把運算符進op棧。等於則棧頂元素出棧。最後再把棧s、op的關係建起來,op裏面的元素爲根結點,s棧裏面的元素爲根的左右孩子。再把新建成的分支進s棧,重複操做,直到op棧頂元素不是'#'。

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

2.2.1設計思路(僞代碼)

定義樹的結構體
主函數作建樹函數的調用和計算帶權路徑長度和
BinTree CreateBtree(string str,int i)
定義BinTree樹BT
if  i>str.size()-1
        return NULL;
if  str[i]=='#'
        return NULL;
生成新結點BT
BT->Data=str[i];
BT->Left=CreateBtree(str,2*i);
BT->Right=CreateBtree(str,2*i+1);
return BT;
void GetWpl(BinTree BT,int &wpl,int h)
if  BT==NULL
    return ;
else
    if  BT的左右孩子都爲空
        wpl+=h*(BT->Data-48);  //字符轉數字(減去'0'=48) 
        h開始從新記錄置爲0
    h++;
    GetWpl(BT->Left,wpl,h);
    GetWpl(BT->Right,wpl,h);

2.2.2代碼截圖(注意,截圖,截圖,截圖。不要粘貼博客上。)


2.2.3本題PTA提交列表說明。

Q1:剛開始在編譯器上運行的結果不是題目中的72
A1:計算wpl時,直接這麼寫wpl+=h*BT->Data,忘記BT->Data是字符,不是數字,因此計算出來的固然不是72。應該改爲wpl+=h*(BT->Data-48),要再減去字符'0'便可,還有就是計算wpl後,h要置爲0,用於其餘葉子結點計算wpl。

2.3 題目3:7-5 jmu-ds-輸出二叉樹每層節點

2.3.1設計思路(僞代碼)

先按題目遞歸法建樹

void LevelOrder(BinTree BT)  //層次遍歷
定義BinTree型隊列qt;
定義int型level,flag;
定義BinTree型curNode,lastNode;
curNode=lastNode=BT;
if BT==NULL 
      輸出NULL
      return ;
else
     BT進隊
     while(!qt.empty())
    {
        if  curNode==lastNode 
        {
            level++;
            用flag來控制輸出level:前是否要換行
            lastNode=qt.back();
        }
        curNode=qt.front();     
        輸出curNode->Data
        if  curNode->Left非空
            curNode->Left進隊
        if  curNode->Right非空
            curNode->Right進隊
        出隊
    }

2.3.2代碼截圖(注意,截圖,截圖,截圖。不要粘貼博客上。)



2.3.3本題PTA提交列表說明。

Q1:怎麼知道每層結點有哪幾個
A1:將根結點進棧,先將curNode,lastNode都置爲BT。只有當curNode,lastNode相等時,即curNode到達每層最後一個元素,再輸出層次。用curNode記錄隊頭,把隊頭的左右孩子進隊,用lastNode記錄隊尾。重複操做,直到隊列爲空。

三、閱讀代碼

3.1 題目

二叉樹剪枝
給定二叉樹根結點 root ,此外樹的每一個結點的值要麼是 0,要麼是 1。返回移除了全部不包含 1 的子樹的原二叉樹。
ide

3.2 解題思路

該題採用後序遍歷的方法,若樹爲空,則返回null。接着遞歸左子樹和右子樹。如有結點左、右孩子都爲空,且該結點的值爲0,則返回努力了,不然返回root

3.3 代碼截圖

3.4 學習體會

這題雖然作法是遞歸,但先序遍歷和後序遍歷有差異,採用先序遍歷則行不通。由於前序只能刪除葉子結點爲0的,但非葉子爲0而且左右結點爲0的狀況卻不行。而採用後序遍歷,效果就不一樣了,後序遍歷從葉子結點開始判斷刪除,如有上述狀況,則那個結點也能成爲葉子結點,從而被刪掉。
因此咱們要全面看待問題,不一樣順序遍歷效果多是不一樣的,這種遍歷順序行不通,其餘種遍歷順序也許就別有洞天,這道題就是一個很好的案例。
相關文章
相關標籤/搜索