在資料結構中,有個很重要的概念就是樹。而二叉樹是一棵特殊的樹,二叉樹每個節點最多有兩個孩子結點,分別稱為左孩子和右孩子。
在一些二叉樹的應用中,常常要求在樹中查詢某種特徵的結點,或是對樹中全部結點逐一進行某種處理,這時候就需要遍歷二叉樹。遍歷二叉樹指的是,按某條搜尋路徑巡訪樹中的每個結點,使得每個結點均被訪問一次,且僅被訪問一次。
在二叉樹的遍歷中最常見的遍歷有三種:前序遍歷、中序遍歷、後序遍歷。當然在遍歷之前我們首先得有棵二叉樹。那麼如何建立一棵二叉樹。根據二叉樹的特點,我們採用二叉鍊錶儲存,用乙個結構體儲存二叉樹結點,如下。
template
t>
struct
binarytreenode
};
下來我們直接進入主題,怎麼對乙個二叉樹進行前序遍歷、中序遍歷、後序遍歷。下圖是乙個簡單的二叉樹,遍歷依次經過的結點也已經標註了。下邊我們直接上**進行遍歷。
1.前序遍歷
因為前序遍歷是先遍歷根,所以我們每次遍歷根,就列印出根結點儲存的資料。然後針對每個子樹,可以在分解成根和它的左子樹和右子樹。
void _prevorder(node* root)
2.中序遍歷中序遍歷的特點是先遍歷左子樹,然後再遍歷根,最後是右子樹。把每乙個結點都當作乙個樹去處理,每一次都是先去訪問它的左子樹。
void _inorder(node* root)
3.後序遍歷後序遍歷是先訪問左子樹,接著是右子樹,最後才是根。處理方法和上面比較類似,就不過多贅餘了。
void _postorder(node* root)
總結一下,二叉樹的遍歷結點,無論是前序、中序還是後序,它處理的方法都是把乙個樹分解成它的某個子樹,然後在把這個子樹看成乙個樹去尋找它的某個結點。
當然在二叉樹中,我們也可能遇到求葉子結點啊,求某層有多少個結點的類似問題。比如,現在求解上面那棵樹的所有葉子結點的個數。如果直接求葉子結點,可能無從下手,那麼我們先求根結點的葉子節點,再去求根節點的葉子結點的葉子結點……不斷把結點去細化。葉子結點是一棵樹中沒有子結點的結點,所以我們的判斷條件是」root->_left == null && root->_right == null「。按照這個思路就有以下**。
size_t _getleafsize(node* root)
同理,如果求二叉樹中第k層的結點數。我們也可以按照這種遞迴的思路去進行求解。我們先求解出k-1層有多少個結點,然後依次求解。**如下。
size_t _getklevelsize(node* root, size_t k)
其實只要和二叉樹有關的問題,我們用到最多的就是遍歷,然後選出符合條件的結點。關於二叉樹的遍歷問題,一定要把握好它求解的精髓——遞迴思想,把乙個大問題無限地縮小,變成它的子問題。子問題的求解就十分簡單了,然後在一層層返回,從而解決大問題。
源**如下:
#include
#include
using
namespace
std;
template
struct binarytreenode
};template
class binarytree
~binarytree()
{}binarytree(t* a, size_t n, const t& invalid = t())
void prevorder()
void inorder()
void postorder()
void levelorder()
cout
<< endl;
}size_t size()
size_t getleafsize()
size_t getklevelsize(size_t k)
protected:
node* _creattree(t* a, size_t n, const t& invalid, size_t& index)
return root;
}void _prevorder(node* root)
void _inorder(node* root)
void _postorder(node* root)
size_t _size(node* root)
size_t _getleafsize(node* root)
size_t _getklevelsize(node* root, size_t k)
protected:
node* _root;
};void testbinarytree()
; binarytree t(array, 10, '#');
t.prevorder();
t.inorder();
t.postorder();
t.levelorder();
cout
<
<< "leafsize:"
<< t.getleafsize() << endl;
cout
<< "k層的節點數:"
<< t.getklevelsize(2) << endl;
}
有關二叉樹的遍歷問題非遞迴
最近在刷題,經常會遇到一些樹的遍歷問題。在之前也寫過部落格詳細講解二叉樹遍歷問題的遞迴實現,可以戳有關二叉樹的遍歷問題去瞅瞅。這篇部落格主要想整理一下非遞迴的實現及遍歷思想。如上圖這是乙個二叉樹。以前序為例,如果我們想直接去遍歷結點,肯定是不行的。首先肯定需要乙個大迴圈,然後一直找左孩子,直到左孩子...
二叉樹遍歷問題
給定二叉樹的先序遍歷和後序遍歷,計算可能有幾棵二叉樹 input 本問題有多組測試資料,第一行是測試資料的組數n,緊接著是n組測試資料。每組測試資料有兩行,分別表示二叉樹的先序遍歷和後序遍歷,每個結點用大寫字母表示,輸入保證資料是正確的。output 對於每一組輸入,對應的輸出只有一行,即符合給定的...
二叉樹的遍歷 二叉樹遍歷與儲存
在資料結構中,二叉樹是非常重要的結構。例如 資料庫中經常用到b 樹結構。那麼資料庫是如何去單個查詢或者範圍查詢?首先得理解二叉樹的幾種遍歷順序 先序 中序 後序 層次遍歷。先序 根節點 左子樹 右子樹 中序 左子樹 根節點 右子樹 後序 左子樹 右子樹 根節點 按層級 class node if c...