1. 程式人生 > >二叉樹的遍歷-遞歸-非遞歸

二叉樹的遍歷-遞歸-非遞歸

node img 空間復雜度 return null 技術 有關 urn 後序

技術分享圖片

二叉樹如上圖所示。

一、遞歸遍歷

#include <iostream>
#include <stack>
using namespace std;

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x): val(x), left(NULL), right(NULL) {}
};

// 先序遍歷,遞歸
// [1] [2] [4] [5] [6] [7] [3]
void preorder1(TreeNode* root) {
    if(!root)   return
; cout << [ << root->val << "] "; preorder1(root->left); preorder1(root->right); } // 中序遍歷,遞歸 // [4] [2] [6] [5] [7] [1] [3] void inorder1(TreeNode* root) { if(!root) return; inorder1(root->left); cout << [ << root->val << "
] "; inorder1(root->right); } // 後序遍歷,遞歸 // [4] [6] [7] [5] [2] [3] [1] void postorder1(TreeNode* root) { if(!root) return; postorder1(root->left); postorder1(root->right); cout << [ << root->val << "] "; }

二、非遞歸遍歷

要借助棧或隊列

// 先序遍歷,非遞歸
void preorder2(TreeNode* root) {
    
if(!root) return; stack<TreeNode*> s; s.push(root); while(!s.empty()) { TreeNode* node = s.top(); cout << [ << node->val << "] "; s.pop(); if(node->right) s.push(node->right); if(node->left) s.push(node->left); } }

初始化把根節點壓棧,訪問根節點並彈出,然後依次將右節點、左節點入棧,直到棧為空。

// 先序遍歷,非遞歸
void preorder3(TreeNode* root) {
   stack<TreeNode*> s;
    while(root != NULL || !s.empty()) {
        if(root != NULL) {
            s.push(root);
            cout << [ << root->val << "] ";
            root = root->left;
        }
        else {
            root = s.top();
            s.pop();
            root = root->right;
        }
    }
}

思路:回溯。訪問根節點的左孩子,訪問左孩子的左孩子,直到左孩子為空,這個過程中把所有訪問過的節點壓棧,當左孩子為空,pop該節點,訪問該節點的右孩子。空間復雜度O(logN) 和樹的深度有關。時間復雜度O(N),所有節點都訪問了一遍。

二叉樹的遍歷-遞歸-非遞歸