思路:
整体和94题类似,借助栈进行操作。
前序遍历:根左右
具体操作:
(假设初始根结点不为空,申请栈空间,这里用Stack数组代替,下标top初始为-1)
先把根结点放入Stack中,这样top!=-1,就可以进行while循环了
①在第一遍while循环中,先把栈中的元素(根节点)取出来记为p,并打印(或保存),然后判断其右孩子结点是否存在,存在则放入Stack中,随后再检测其左孩子结点是否存在,存在则放入Stack中。
②注意,在①操作中,我们是先检测的是右孩子结点再检测的是左孩子结点,这样如果p有两个孩子结点,那么入栈顺序就是右左,出栈顺序就是左右,
③现在进入第二遍while循环,这个时候p=p->left,并以此为新的根节点来进行①②操作,
④直到进行到最左边结点的时候,栈中只剩下一部分子树的右孩子结点,然后重复执行上述三步,即可完成遍历
⑤判断遍历完成的标志是,进行到最右边的孩子结点时,执行完打印(或保存)后,top==-1,且没有新的左右子节点填入,这个时候while循环结束
(自己画一个三层的二叉树即可发现规律)
#include<iostream>
#include<cstdlib>
#include<vector>
#include<stack>
using namespace std;
typedef struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
} TreeNode,*SearchTree;
SearchTree MakeEmpty(SearchTree T)
{
if(T!=NULL)
{
MakeEmpty(T->left);
MakeEmpty(T->right);
free(T);
}
T = NULL;
return T;
}
SearchTree Insert(int val,SearchTree T)
{
if(T==NULL)
{
T = (SearchTree)malloc(sizeof(TreeNode));
if(T==NULL)
{
printf("MALLOC ERROR\n");
exit(1);
}
T->val = val;
T->left = T->right = NULL;
}
else
{
if(T->val>val)
T->left = Insert(val,T->left);
else if(T->val<val)
T->right = Insert(val,T->right);
}
return T;
}
void InOrderTraversal(SearchTree T)
{
if(T==NULL)
return ;
InOrderTraversal(T->left);
printf("%d ",T->val);
InOrderTraversal(T->right);
}
class Solution
{
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> v;
if(root!=NULL)
{
TreeNode *Stack[100];
int top = -1;
TreeNode *p = root;
Stack[++top] = p;
while(top!=-1)
{
p = Stack[top--];
v.push_back(p->val);
if(p->right!=NULL)
Stack[++top] = p->right;
if(p->left!=NULL)
Stack[++top] = p->left;
}
}
return v;
}
};
int main()
{
Solution s;
vector<int> v;
SearchTree T = NULL;
T = Insert(1,T);
T = Insert(2,T);
T = Insert(3,T);
T = Insert(0,T);
InOrderTraversal(T);
cout<<endl;
v = s.preorderTraversal(T);
cout<<endl;
vector<int>::iterator it;
for(it = v.begin(); it!=v.end(); it++)
{
cout<<*it<<" ";
}
return 0;
}