只有先序遍历部分的源代码: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