有關二叉樹的遍歷問題

2021-07-28 23:08:21 字數 2931 閱讀 3339

在資料結構中,有個很重要的概念就是樹。而二叉樹是一棵特殊的樹,二叉樹每個節點最多有兩個孩子結點,分別稱為左孩子和右孩子。

在一些二叉樹的應用中,常常要求在樹中查詢某種特徵的結點,或是對樹中全部結點逐一進行某種處理,這時候就需要遍歷二叉樹。遍歷二叉樹指的是,按某條搜尋路徑巡訪樹中的每個結點,使得每個結點均被訪問一次,且僅被訪問一次。

在二叉樹的遍歷中最常見的遍歷有三種:前序遍歷中序遍歷後序遍歷。當然在遍歷之前我們首先得有棵二叉樹。那麼如何建立一棵二叉樹。根據二叉樹的特點,我們採用二叉鍊錶儲存,用乙個結構體儲存二叉樹結點,如下。

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...