【面试题】不用递归实现二叉树的遍历(使用栈)

只有先序遍历部分的源代码:https://github.com/cr19941016/preOrderTree
实现环境:ubuntu16.04 + cmake3.5.1
先序遍历递归的本质就是循环和栈

void TreeHandler::myPreOrder(TreeNode* root){    // 非递归先序遍历二叉树git
    cout << "mypre: ";
    if(!root)
        return;
    stack<TreeNode*> stk;
    stk.push(root);
    while(!stk.empty()){
        TreeNode* p = stk.top();
        cout << p->data << " ";
        stk.pop();
        if(p->rightchild){
            stk.push(p->rightchild);
        }
        if(p->leftchild){
            stk.push(p->leftchild);
        }
    }
    cout << endl;
}

中序遍历:

void TreeHandler::myMidOrder(TreeNode* root){
	cout << "mymid: ";
	stack<TreeNode*> stk;
	TreeNode* p = root;
	while(p || !stk.empty()){
		while(p){
			stk.push(p);
			p = p->leftchild;
		}
		if(!stk.empty()){
			p = stk.top();
			stk.pop();
			cout << p->data << ' ';
			p = p->rightchild;
		}
	}
	cout << endl;
}

后序遍历(比较麻烦,另一种解法是采用一个指针保存上次遍历的节点,避免重复遍历),使用两个栈,一个负责按照“根、右、左”的顺序入栈出栈,另一个负责逆序记录输出的数据:

void TreeHandler::myPostOrder(TreeNode* root){
	cout << "mypost: ";
	if(!root){
		return;
	}
	stack<TreeNode*> stk1; // 辅助栈
	stack<TreeNode*> stk2; // 逆序记录遍历的数据
	TreeNode* p = root;
	while(p || !stk1.empty()){
		if(p){
			stk2.push(p);
			stk1.push(p);
			p = p->rightchild;
		}
		else{
			p = stk1.top();
			stk1.pop();
			p = p->leftchild;
		}

	}

	while(!stk2.empty()){
		p = stk2.top();
		stk2.pop();
		cout << p->data << ' ';
	}
	cout << endl;
}

其他:使用队列将数组转化为生成二叉树

#include "preodertree.h"
TreeNode* TreeHandler::createTree(vector<int> &nums){ // 根据数组生成二叉树,如果数值为-1则表示空位
    TreeNode* root = NULL;
    if(nums.empty()){
        return root;
    }
    root = new TreeNode(nums[0]);
    queue<TreeNode*> q;
    q.push(root);
    for(unsigned int i = 1; i < nums.size(); ){
        TreeNode* p = q.front();
        if(nums[i] != -1){
            TreeNode* l = new TreeNode(nums[i]);
            p->leftchild = l;
            q.push(l);
            i++;
        }
        else i++;
        if(i < nums.size() && nums[i] != -1){
            TreeNode* r = new TreeNode(nums[i]);
            p->rightchild = r;
            q.push(r);
            i++;
        }
        else i++;
        q.pop();
    }
    return root;
}

此外,不使用栈,空间复杂度为O(1),时间复杂度为O(n)的Morris Traversal算法:
https://www.jianshu.com/p/d2059062efac

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章