二叉樹的遍曆方法

來源:互聯網
上載者:User

標籤:des   blog   http   os   io   ar   for   2014   div   

    今天學習到二叉樹的時候,看到了二叉樹的先序,後序,中序遍曆方法。然而二叉樹遍曆方法遞迴實現十分簡單,迭代版本實現起來些許複雜,就又上手試試二叉樹的各種遍曆方法以及實現版本,當是溫習一遍之前瞭解到的實現方法。

    三種遍曆方法中遞迴實現難度相當,代碼相當簡略。

    三種遍曆方法中利用棧實現的迭代版本中,先序和中序實現難度相對簡單,但是後序遍曆方法實現起來比較複雜,這裡實現思路也不同於之前先序和中序的版本。

    另外一種O(1)空間複雜度實現先序,中序實現難度也相對簡單,後序相對複雜。

    以下貼出完整測試代碼,main函數中輸入產生二叉樹的方法:

    輸入節點數量,然後輸入二叉樹樹形結構1,2,3,#,4其中#代表空,則1,2,3,#,4代表以下結構:

    

       1     /       2     3     \       4

   再舉一個例子,輸入7個節點數量,輸入1,2,3,4,5,6,7代表樹形結構如下:

    

                     1                   /                    2    3                /  \  /                 4   5  6   7

   代碼:

     其中_r尾碼的為遞迴實現,_s尾碼的為利用棧迭代實現,_m尾碼的為O(1)空間複雜度迭代實現。

     其中_m迭代實現線程不安全,因為臨時的改變了樹的結構。

#include <iostream>#include <stack>#include <vector>using namespace std;struct TreeNode {int label;TreeNode *right;TreeNode *left;TreeNode(int temp):label(temp) {}};class Solution {public:void inordertraversal_r(TreeNode *root) {if(root == NULL) {return;}inordertraversal_r(root->left);cout<<root->label<<" ";inordertraversal_r(root->right);}void preordertraversal_r(TreeNode *root) {if(root == NULL) {return;}cout<<root->label<<" ";preordertraversal_r(root->left);preordertraversal_r(root->right);}void postordertraversal_r(TreeNode *root) {if(root == NULL) {return;}postordertraversal_r(root->left);postordertraversal_r(root->right);cout<<root->label<<" ";}void inordertraversal_s(TreeNode *root) {stack<TreeNode*> s;TreeNode *cur = root;while(!s.empty() || cur != NULL) {while(cur != NULL) {s.push(cur);cur = cur->left;}cur = s.top();s.pop();cout<<cur->label<<" ";cur = cur->right;}}void preordertraversal_s(TreeNode *root) {stack<TreeNode*> s;TreeNode *cur = root;while(!s.empty() || cur != NULL) {while(cur != NULL) {cout<<cur->label<<" ";s.push(cur);cur = cur->left;}cur = s.top();s.pop();cur = cur->right;}}//change thinking , it‘s too hardvoid postordertraversal_s(TreeNode *root) {//the original method/*We use a prev variable to keep track of the previously-traversed node. Let’s assume curr is the current node that’s on top of the stack. When prev is curr‘s parent, we are traversing down the tree. In this case, we try to traverse to curr‘s left child if available (ie, push left child to the stack). If it is not available, we look at curr‘s right child. If both left and right child do not exist (ie, curr is a leaf node), we print curr‘s value and pop it off the stack.If prev is curr‘s left child, we are traversing up the tree from the left. We look at curr‘s right child. If it is available, then traverse down the right child (ie, push right child to the stack), otherwise print curr‘s value and pop it off the stack.If prev is curr‘s right child, we are traversing up the tree from the right. In this case, we print curr‘s value and pop it off the stack.*/if(root == NULL) {return;}stack<TreeNode*> s;s.push(root);TreeNode *cur = NULL;TreeNode *pre = NULL;while( !s.empty() ) {cur = s.top();//left down or right downif( pre == NULL || pre->left == cur || pre->right == cur) {if(cur->left != NULL) {s.push(cur->left);}else if(cur->right != NULL) {s.push(cur->right);}else {cout<<cur->label<<" ";s.pop();}}//left upelse if(cur->left == pre) {if(cur->right != NULL) {s.push(cur->right);}else {cout<<cur->label<<" ";s.pop();}}//right upelse if(cur->right == pre) {cout<<cur->label<<" ";s.pop();}pre = cur;}/* the easy methodstack<TreeNode*> s;s.push(root);TreeNode *cur = NULL;TreeNode *pre = NULL;while( !s.empty() ) {cur = s.top();if(pre == NULL || pre->left == cur || pre->right == cur) {if(cur->left != NULL) {s.push(cur->left);}else if(cur->right != NULL) {s.push(cur->right);}}else if(cur->left == pre) {if(cur->right != NULL) {s.push(cur->right);}}else {cout<<cur->label<<" ";s.pop();}pre = cur;}*/}void inordertraversal_m(TreeNode *root) {TreeNode *cur = root;TreeNode *pre = NULL;while(cur != NULL) {if(cur->left == NULL) {cout<<cur->label<<" ";cur = cur->right;}else {pre = cur->left;while( pre->right != NULL && pre->right != cur ) {pre = pre->right;}if(pre->right == NULL) {pre->right = cur;cur = cur->left;}else {pre->right = NULL;cout<<cur->label<<" ";cur = cur->right;}}}}void preordertraversal_m(TreeNode *root) {TreeNode *cur = root;TreeNode *pre = NULL;while(cur != NULL) {if(cur->left == NULL) {cout<<cur->label<<" ";cur = cur->right;}else {pre = cur->left;while( pre->right != NULL && pre->right != cur ) {pre = pre->right;}if(pre->right == NULL) {pre->right = cur;cout<<cur->label<<" ";cur = cur->left;}else {pre->right = NULL;cur = cur->right;}}}}//this is the most difficult algorithmvoid reverse_out(TreeNode *from,TreeNode *to) {//first reverse from->to//reverseTreeNode *cur = from;TreeNode *post = cur->right;while(cur != to) {TreeNode *tmp = post->right;post->right = cur;cur = post;post = tmp;}//already reverse,output listTreeNode *traversal = cur;while( cur != from ) {cout<<cur->label<<" ";cur = cur->right;}cout<<cur->label<<" ";//reverse originalcur = to;post = cur->right;while(cur != from) {TreeNode *tmp = post->right;post->right = cur;cur = post;post = tmp;}//restore to‘s rightto->right = NULL;}void postordertraversal_m(TreeNode *root) {TreeNode *newroot = new TreeNode(0);newroot->left = root;newroot->right = NULL;TreeNode *cur = newroot;TreeNode *pre = NULL;while(cur != NULL) {if(cur->left == NULL) {    cur = cur->right;}else {pre = cur->left;while(pre->right != NULL && pre->right != cur) {pre = pre->right;}if(pre->right == NULL) {pre->right = cur;cur = cur->left;} else {pre->right = NULL;reverse_out(cur->left,pre);cur = cur->right;}}}}};int main(void) {int nodecount;while( cin>>nodecount && nodecount != 0 ) {vector<TreeNode*> treenodes;while(nodecount) {nodecount--;int nodelabel;cin>>nodelabel;if( ((char)nodelabel) == ‘#‘ ) {treenodes.push_back( NULL );}else {treenodes.push_back( new TreeNode(nodelabel) );}}//construct the treefor(int i = 0;i < treenodes.size();i++) {if( treenodes[i] == NULL ) {continue;}else {//left child node 2n+1,right child node 2n+2if( 2*i + 1 < treenodes.size() ) {treenodes[i]->left = treenodes[2*i + 1];}else {treenodes[i]->left = NULL;}if( 2*i + 2 < treenodes.size() ) {treenodes[i]->right = treenodes[2*i + 2];}else {treenodes[i]->right = NULL;}}}Solution s;cout<<"inorder recursion  :";s.inordertraversal_m(treenodes[0]);cout<<endl;cout<<"inorder stack      :";s.inordertraversal_s(treenodes[0]);cout<<endl;cout<<"inorder morris     :";s.inordertraversal_r(treenodes[0]);cout<<endl;cout<<"preorder recursion :";s.preordertraversal_m(treenodes[0]);cout<<endl;cout<<"preorder stack     :";s.preordertraversal_s(treenodes[0]);cout<<endl;cout<<"preorder morris    :";s.preordertraversal_r(treenodes[0]);cout<<endl;cout<<"postorder recursion:";s.postordertraversal_m(treenodes[0]);cout<<endl;cout<<"postorder stack    :";s.postordertraversal_s(treenodes[0]);cout<<endl;cout<<"postorder morris   :";s.postordertraversal_r(treenodes[0]);cout<<endl;for(int i = 0;i < treenodes.size();i++) {delete treenodes[i];}}}

  關於morris的先序,中序思路圖解:

  

      關於moriis的後序思路圖解:

    

二叉樹的遍曆方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.