資料結構 二叉樹的三種遍歷 (遞迴 非遞迴)

2021-08-08 11:31:58 字數 2487 閱讀 3734

前序遍歷:根節點—>左子樹—>右子樹

中序遍歷:左子樹—>根節點—>右子樹

後序遍歷:左子樹—>右子樹—>根節點

【構造一棵樹】

我們用陣列存樹的節點

int a[15] =

「#」代表非法值,就是為空的節點

#include

#include

#include

using

namespace

std;

template

< class t>

struct binarytreenode

};template

class binarytree

binarytree(const t* a, size_t n, const t& invalid)

//構造樹

node* _creattree(const t*a, size_t n, const t& invalid, size_t& index)

return root;

}~binarytree()

protected:

node* _root;

前序——–遞迴

前序就是遇到根節點就訪問,之後訪問左子樹,再右子樹,所以很容易可以寫出如下非遞迴**

void prevorder()

void _prevorder(node* root)

cout << root->_data <<

" ";

_prevorder(root->_left);

_prevorder(root->_right);

}

前序——–非遞迴

這裡我們要借用棧,因為棧的特性是後進先出。

先遍歷樹的最左節點,並把每個節點入棧。在入棧的同時就可以訪問根節點。

當cur為null時,這顆樹的最左邊的根節點節點都全部入棧,

然後取出棧頂節點,訪問右子樹,

當棧為空,這個樹就遍歷結束

void prevorder_nonr()//非遞迴前序遍歷

node* top = s.top();

s.pop();

cur = top->_right;

}cout

<< endl;

}

中序—-遞迴

void inorder()//中序

void _inorder(node* root)

_inorder(root->_left);

cout << root->_data <<

" ";

_inorder(root->_right);

}

中序—-非遞迴

依然借助棧,把樹的最左邊的根節點cur全部入棧,

然後依次取棧頂節點訪問,

再訪問右子樹,右子樹不為空的時候繼續入棧。

void inorder_nonr()//非遞迴中序遍歷

node* top = s.top();//此時訪問的是最左節點

cout

<< top->_data << " ";

s.pop();

cur = top->_right;

}cout

<< endl;

}

後序—-遞迴

void posorder()//後序

void _posorder(node* root)

_posorder(root->_left);

_posorder(root->_right);

cout << root->_data <<

" ";

}

後序—-非遞迴

還是借助棧。但是此時有乙個問題:後序是先訪問左子樹,在右子樹,最後根節點,那麼問題來了:–訪問右子樹,是需要通過先訪問根節點,當cur=top->_right,cur不是null,把cur入棧,依次訪問右子樹,最後依次退到根節點訪問,但是此時cur=top->_right,cur不等於null,再次入棧;可是我們已經把右樹訪問過了,所以我們會在這裡陷入死迴圈。

那麼如何解決呢?

我們可以設定乙個標記prev,prev表示上乙個訪問的節點。當我們取出棧頂節點時,如果他的右子樹已經訪問過了,就不再把右子樹入棧,而直接訪問當前節點。

void postorder_nonr()//後序非遞迴

node* top = s.top();

if (top->_right == null || top->_right == prev)

else

}cout

<< endl;

}

二叉樹的三種非遞迴遍歷

一.前序遍歷 前序遍歷按照 根結點 左孩子 右孩子 的順序進行訪問。1.遞迴實現 void preorder1 bintree root 遞迴前序遍歷 2.非遞迴實現 根據前序遍歷訪問的順序,優先訪問根結點,然後再分別訪問左孩子和右孩子。即對於任一結點,其可看做是根結點,因此可以直接訪問,訪問完之後...

二叉樹的三種非遞迴遍歷

遞迴演算法和非遞迴演算法的轉換 可以借助棧,將二叉樹的遞迴演算法轉換為非遞迴演算法,下面以中序遍歷為例給出中序遍歷的非遞迴演算法。先掃瞄 並非訪問 根結點的所有左結點並將他們一一進棧。然後出戰乙個結點 p 顯然結點 p沒有左孩子結點或者左孩子結點均已訪問過 則訪問它。然後掃瞄該結點的有孩子結點,將其...

二叉樹的三種非遞迴遍歷

struct treenode 一 前序輸出二叉樹 void preorder treenode root p stk.top stk.pop p p right 二 中序輸出二叉樹 void midorder treenode root p stk.top cout void postorder ...