1. 程式人生 > >第五章小結與習題小結

第五章小結與習題小結

tails http 有意思 細節 下標 如果 因此 方式 cout

第五章應該是一條分割線了,前面四章講的都是線性結構,接下來的就是非線性結構了。無疑問的是非線性結構是要比線性結構要難的了,畢竟從一對一到一對多還是有一定的差距的。哈哈,其他的也不多說了,我們開始這一章的小結吧。

正如第五章的題目“樹和二叉樹”一般,我也覺得這一章的學習就是分為兩個部分,一個是樹,一個則是二叉樹。

對於普通的樹,我覺得我們主要是要掌握它的一些基本的術語,這會使得後面的操作更加的清晰明了。我小結了一下,大概可以如下圖一般,概念可能比較難記,結合圖來記會使記憶更加牢固。

技術分享圖片

接下來,我們就來看看這一章的大頭了。二叉樹顧名思義,就是一個節點至多只有兩顆子樹的樹,左邊的為左子樹,右邊則為右子樹。二叉樹作為特殊的樹,普通的樹的概念自然適用於二叉樹。當然,二叉樹也有特別的一些概念。覺得以下這兩個概念比較容易混淆,在這裏做個區別。

滿二叉樹:

深度為k且含有2^k -1個結點的二叉樹,通俗來講就是每一個層次都填滿的二叉樹。

完全二叉樹:

  1. 葉子結點只可能在層次最大的兩層上出現。
  2. 最後一層之前為滿二叉樹,最後一層靠左對齊。

還是和之前學習線性結構一樣,接下來要考慮的就是具體的存儲結構和操作了。存儲結構也還是分為了順序存儲和鏈式存儲,但其中還可以分出四種不同的標識方法:雙親表示法,孩子表示法,雙親孩子表示法以及孩子兄弟表示法。

對於二叉樹的特殊結構也引出了四種特殊的遍歷的方法:先序遍歷,中序遍歷,後序遍歷以及層次遍歷。前面三種遍歷有著同工異曲之妙,在這裏就只介紹中序遍歷。

中序遍歷的具體操作定義:

若二叉樹為空,則進行空操作,否則:

  1. 中序遍歷左子樹
  2. 訪問根節點
  3. 中序遍歷右子樹

從定義來看,很明顯這是一個遞歸的操作,根據定義則可以得到代碼如下:

1 public void inOrderTraverse1(TreeNode root) {  
2         if (root != null) {  
3             inOrderTraverse1(root.left);  
4            cout<<root.data;5             inOrderTraverse1(root.right);  
6 } 7 }

在做題的時候就碰到了要求層次遍歷的題目,及由左到右,由上到下對樹進行一個遍歷。不瞞你說,我確實沒想到什麽好的方法,但是百度了一下我就恍然大悟了,使用隊列先進先出的性質正好就和要求相呼應。以下是我在CSDN上找到的一篇博客,我覺得很有意義,這裏分享一下:

https://blog.csdn.net/hansionz/article/details/81947834

技術分享圖片

我覺得這一次的作業和實踐的題目都比較有意思,所以在這裏也來談論一下。

首先是第一題:輸出樹節點。

這道題給我最大的困擾就是輸入了。平常我們所遇到的輸入都是比較簡單的純粹的輸入,而這一次一開始我看了很久都沒有看出來,輸入究竟是什麽意思。

技術分享圖片

一開始的時候以為這一個一個節點就是順著排的,就像第二行輸入,節點左子樹的編號為1,而右子樹為空。這樣一理解後,我就畫不出來圖了。後來又反復讀了很多次的題目,才明白1是指第一個節點。

技術分享圖片

(失敗的探索過程

明白了題目的意思之後,輸入的問題也就得到了解決。發現了這道題目與下標密切關系,於是我便選擇了數組的存儲形式。

技術分享圖片

接下來就是一些細節問題,因為輸入的時候,在為空的時候題目給了符號-’來表示,因此我們需要在輸入的時候以字符的形式進行輸入,而後根據其ASCII碼再轉化為整型。

在這裏,還很容易出現一個問題,就是我們往往只關註了輸入的內容,卻忘記了題目自身的條件。如上圖我所定義的結構類型,其中有一個data,實際上就是代表第幾個節點,即下標。

但我們在初始化的時候往往會忘記給data初始化,最後就導致該值為隨機值,答案也得不到正確的。

技術分享圖片

接下來就是層次遍歷輸出樹節點了,這裏上面的時候已經進行了說明,但這裏還是要強調的是,正如老師上課講的,我們要明確在隊列裏面排列的是什麽,是地址,還是下標,又或者是其他的。一開始我就是沒有明白究竟在隊列裏面排列的是什麽,導致了後面的思路一團亂

其實深入虎穴和前面的這道題是差不多一樣的道理,只是從二叉樹變成了普通的樹,實際上存儲的方式並沒有太大的改變。但由於題目的數據比較大,而且不確定這個時候采用動態的數組使得題目更加容易得到解決。一開始我采用了二維數組的形式,理解確實好理解,但運行的時候就內存爆了。

最後要講的就是同構樹這一題了。看到這道題題目的時候,我就想著能不能投機取巧,直接進行判斷對比,連樹都不構建,後來發現題目並不是那麽簡單,是經過若幹次的左右子樹對調若能兩棵樹可以吻合就為同構。

於是我便開始踏踏實實一步一步來了。首先將兩棵樹構建起來。對於這道題一開始我真的沒想到用遞歸的辦法,我就一直在想怎麽樣一層一層的對比,畢竟只是左右子樹的對調,於是我就利用了之前學的層次遍歷的方法,一層一層的比較。

具體的思路就是在入隊前進行一個判斷,看兩棵樹左右子樹根是否相同或者相反,相同則正常進行入隊,如果相反則將第二顆樹先右後左進行入隊

技術分享圖片

雖然有點笨,但是做出來感覺還是不錯的。後來去網上借鑒的時候,看到了遞歸的方法,也覺得確實比我的方法更加的機智。

技術分享圖片

後來過pta的時候,也還是出現了問題,缺少了空樹的情況。

技術分享圖片

雖然只是一個句子可以搞定的問題,但卻有時會是一個巨大的漏洞。

上一次的目標基本完成了,較好的掌握了KMP算法,因為這一次的實踐題老師帶我們領略了一下STL的魅力,我下一次的目標就想多去了解一些關於STL方面的知識。

第五章小結與習題小結