DS博客做業05——樹

1.本週學習總結(0--2分)

1.思惟導圖

ios

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

不一樣類型的樹之間是能夠相互轉化的,好比一顆普通的樹能夠經過特定的過程轉化成二叉樹,也能夠轉化成森林,反之亦然。
樹也存在着多種的存儲結構,例如:雙親存儲,孩子鏈存儲,孩子兄弟存儲
二叉樹是最多見的樹,咱們詳細的學歷了二叉樹的建立、消除等等基本構造二叉樹的方法,也學習瞭如何用先序加中序,中序加後序來進行樹的構建。經過二叉樹的學習,咱們又學習了線索二叉樹,和哈夫曼樹,這兩個知識點都是在二叉樹的基礎上進行昇華的。
線索二叉樹能夠輕易的獲得該結點的相鄰的結點,而哈夫曼樹則能夠用來求解最優解的問題。

2.PTA實驗做業(6分)

2.1.根據後序和中序遍歷輸出先序遍歷

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

2.1.1設計思路(僞代碼)

以樣例爲例
函數

//僞代碼(BinTree CreatBt函數)
if n=0 then
    return 0
end if
定義一個BinTree類型的變量BT//構造結點
定義一個int型變量mid//用於儲存in數組中,該結點的位置
for i=0 to n do
    if in[i]與post[n-1]相等 then
        將i賦值給mid
        break;
    end if
end for
將post[n-1]的值賦給BT->data
BT->lchild =CreatBt(post,in,mid)//遞歸建立左孩子
BT->rchild =CreatBt(post+mid,in+1+mid,n-1-mid)//遞歸建立右孩子

2.1.2代碼截圖



2.1.3本題PTA提交列表說明。

Q1:一連串的編譯錯誤……快把我搞瘋掉
A1:然而,全都是一些基本的錯誤,好比把 寫成了 ;上面結構體寫的BTNode,下面定義變量的時候,又寫成了TNode之類的。(吐血)
Q2:其實,他提示的錯誤點,我沒看懂

A2:而後,就到編譯器上去調試了,結果才發現,我定義的變量mid沒賦值,我也傳參傳的好好的。
post

2.2 jmu-ds-輸出二叉樹每層節點

層次遍歷樹中全部節點。輸出每層樹節點。
樹結構按照樹的先序遍歷遞歸建樹,好比先序遍歷字符串「ABD#G###CEH###F#I##」#表明空節點。

2.2.1設計思路(僞代碼)

//設計思路
利用隊列,將二叉樹按行存入隊列中,利用flag,當flag爲1時表明,curNode在該行的第一個位置,當flag=0時,依次出隊輸出,直到curNode與該行的隊尾指針lastNode相等時,進入下一行的掃描。
//僞代碼(LevelOrder函數)
定義BinTree型的隊列qt
定義int型變量level並賦初值爲0,用於表示行數;flag並賦初值爲1,用於判斷是否爲每行開頭
定義BinTree型變量curNode、lastNode//分別指向當點結點和該行的最後一個結點,並將bt賦值給兩個變量
if bt不爲空 then
    將bt存入隊列qt中
end if
while qt不爲空 do
    將隊頭賦值給curNode
    if curNode的左孩子不爲空  then
        將curNode的左孩子入隊
    end if
    if curNode的右孩子不爲空  then
        將curNode的右孩子入隊
    end if
    if flag的值爲1 then
        輸出「++level:」
    end if
    if curNode與lastNode相等 then
        將qt的隊尾的值賦給lastNode
        輸出當前結點的值和一個逗號
        將1賦給flag
    else
        if lastNode不等於curNode的左孩子
            輸出當前結點的值和一個逗號
        end if
        將0賦給flag
    end if
    將隊列的隊頭出隊
end while

2.2.2代碼截圖



2.2.3本題PTA提交列表說明。

Q1:提交列表顯示的是不空的時候出錯(有兩個不空的測試點),當時測試樣例能過,可是並不知道哪裏有錯。
A1:而後就開始本身編數據,想一想各類數據的可能狀況,而後就想到一個要是最後一行的葉子結點是上一行結點的左孩子,這個代碼好像不能運行出來

結果,事實證實,真的不能……

Q2:而後就針對要是最後一個葉子節點是左孩子的狀況進行改進。一運行,測試樣例過了,一提交,又是部分正確。。。
A2:而後,瘋狂編數據,發現,這麼改完之後,有時候最後一個葉子結點會輸出兩次。
Q3:再次修改,(忘了當時怎麼想的,反正一直改,一直調試)最後,我所能想到的數據都過了。開開心心的提交,部分正確。
A3:改不動了,是在是不知道該朝哪一個方向進行修正,而後借鑑了同窗的思路,發現只要一行到結尾的時候,將隊尾的值賦給lastNode就實現了lastNode指向下一行的行末了。學習

2.3 修理牧場

農夫要修理牧場的一段柵欄,他測量了柵欄,發現須要N塊木頭,每塊木頭長度爲整數L​i​​ 個長度單位,因而他購買了一條很長的、能鋸成N塊的木頭,即該木頭的長度是L​i​​ 的總和。可是農夫本身沒有鋸子,請人鋸木的酬金跟這段木頭的長度成正比。爲簡單起見,不妨就設酬金等於所鋸木頭的長度。例如,要將長度爲20的木頭鋸成長度爲八、7和5的三段,第一次鋸木頭花費20,將木頭鋸成12和8;第二次鋸木頭花費12,將長度爲12的木頭鋸成7和5,總花費爲32。若是第一次將木頭鋸成15和5,則第二次鋸木頭花費15,總花費爲35(大於32)。請編寫程序幫助農夫計算將木頭鋸成N塊的最少花費。

2.3.1設計思路(僞代碼)

//設計思路
利用有限隊列的升序排列,自動將模板長度從小到大排列,每次取出兩個最小值,將兩個值相加,再存放到隊列中,自動排序...直到隊列爲空。這個過程能夠看做是切木板的逆過程。先找出最小的兩塊拼在一塊兒,而後放回木板堆中,再找出最小的兩塊木板拼在一塊兒,直至整條木板拼接完成。這樣就能夠實現木板割據的最小費用。
//僞代碼
定義int型變量num一、num2分別用於存放隊列中最小的兩個數
定義int型變量add用於存放num一、num2的切割費用和,sum用於計算總薪酬,並附sum初值0
定義優先序列q,並將q自動升序排列
for i=0 to n do
    輸入number
    將number存入隊列q中
end for
while 隊列q的長度大於1 do
    將隊頭的值賦給num1
    將隊頭出隊
    將此時隊頭的值賦給num2
    將此時的隊頭出隊
    將num1與num2的和賦給add  //逆過程當中的最小切割費用
    sum等於sum加上add的值
    將add存入隊列q中
end while
輸出sum的值

2.3.2代碼截圖



ps:截圖中的註釋應該是升序排列,而不是降序排列測試

2.3.3本題PTA提交列表說明。

Q1:作這道題以前,老師有在交流羣裏說,這道題用哈弗曼樹作的話會運行超時,能夠用容器中的優先隊列作。
A1:當時還不會優先隊列,就想着排序的話,用數組作,再用一個sort函數就能夠搞定了,每循環一次,調用一次sort函數。後來想一想優先隊列有一個好處,就是能夠自動排序。而後就想多學一個stl容器也不錯,就去找了有限隊列的相關知識點。

三、閱讀代碼(-2--2分)

3.1 玩轉二叉樹

給定一棵二叉樹的中序遍歷和前序遍歷,請你先將樹作個鏡面反轉,再輸出反轉後的層序遍歷的序列。所謂鏡面反轉,是指將全部非葉結點的左右孩子對換。這裏假設鍵值都是互不相等的正整數。

輸入格式:

輸入第一行給出一個正整數N(<=30),是二叉樹中結點的個數。第二行給出其中序遍歷序列。第三行給出其前序遍歷序列。數字間以空格分隔。

輸出格式:

在一行中輸出該樹反轉後的層序遍歷的序列。數字間以1個空格分隔,行首尾不得有多餘空格。

輸入樣例:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
輸出樣例:
4 6 1 7 5 3 2

3.2 解題思路

這道題的解題很是的巧妙,一般人的思路多是將正常的先序序列求出來,在將其逆序。而這個解題則是採起在層次遍歷時,先將其右孩子存入數組中,再將其左孩子存入數組中的作法。

3.3 代碼截圖


3.4 學習體會

  • 在解題時,不要固性思惟,能夠多想一想新的解題思路。
  • 能夠經過學習別人的優秀代碼,來擴寬本身的解題思路。有時候作題可能就會有意想不到的收穫。
相關文章
相關標籤/搜索