一、“先、中、后”遍历算法的统一递归写法
void pre(BtNode * p){//先序:根左右
if(p!=NULL){
visit(p);
pre(P->Lchild);
pre(P->Rchild);
}
}
注意:结合中先、中后、中层均可确定二叉树的结构
二、“先、中、后”遍历算法的非递归写法:栈——向左压栈,退栈向右
先:左侧不断压栈到叶子,空了退栈向右,左侧不断压栈。压栈时输出
中:左侧不断压栈到叶子,空了退栈向右,左侧不断压栈。退栈时输出
后:左侧不断压栈到叶子,空或已访问了回栈,右侧不断压栈到叶子,空或已访问退栈,在退栈向右。第二次压栈时输出
2.1 中序遍历非递归实现:根节点断入栈,向左遍历; 不能向左时,退栈,输出,向右遍历。
void InOrderTraverse(BiTree T)//非递归中序遍历
{
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T || !Stack.empty())
{
while(T)
{
Stack.push(T);
T=T->lchild;
}
if(!Stack.empty()){
T=Stack.top();
Stack.pop();
printf("%c",T->data);
T=T->rchild;
}
}
}
2.2 先序遍历非递归实现:输出,跟节点不断入栈,向左遍历;不能向左时,退栈向右。
void PreOrderTraverse(BiTree T)//非递归先序遍历
{
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T || !Stack.empty())
{
while(T)
{
Stack.push(T);
printf("%c",T->data);
T=T->lchild;
}
if(!Stack.empty()){
T=Stack.top();
Stack.pop();
T=T->rchild;
}
}
}
另一种思路,首先需要先从栈顶取出节点,然后访问该节点,如果该节点不为空,则访问该节点,同时把该节点的右子树先入栈,然后左子树入栈。循环结束的条件是栈中不在有节点。即 !s.empty()
public void preOrder(Node root) {
Stack<Node> s = new Stack<Node>();
s.push(root);
Node p = null;
while (!s.empty()) {
p = s.pop();
if (p != null) {
System.out.print(p.val+" ");
s.push(p.right);
s.push(p.left);
}
}
}
2.3 后序遍历非递归实现:根节点入栈,向左遍历;左不能遍历:回退,向右:向右不能遍历时,退栈,输出,退栈右; +一个验证是否已经访问过
void postorderTraversal(TreeNode* root) {
if(root==NULL){
return ;
}
stack<TreeNode *> sts;
map<TreeNode *,bool> maps;//记录是第几次访问
TreeNode * p=root;
while(!sts.empty() || p){
while(p){
sts.push(p);
maps[p]=false;
p=p->left;
}
if(!sts.empty()){
TreeNode * temp=sts.top();
if(maps[temp]==false){ //如果只访问过一次,则先访问其右子树,顺便设为访问过两次
maps[temp]=true;
p=temp->right;
}else{ //如果访问过两次,则出栈,并打印。
res.push_back(temp->val);
sts.pop();
}
}
}
return ;
}
另一种思路: 根右左遍历入队,然后反向输出
三、层次遍历:队列
void PostOrderTraverse(BiTree T)//非递归先序遍历
{
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
if(T!=null)
{
push(T);
while(q&&front!=rear){
q=pop(front);
visit(q);
if(q->lchild) push(q->lchild);
if(q->rchild) push(q->rchild);
}
}
}
层次遍历查找深度
int treeDepth(BinaryTree* root) {
if (root == nullptr) return 0;
int depth = 0;
queue<BinaryTree*> que;
que.push(root);
while (!que.empty()) {
depth++;
int count = 0;
int size = que.size();
while (count < size) { //弹出当前层的所有节点
BinaryTree *front = que.front();
que.pop();
count++;
if (front->left)
que.push(front->left);
if (front->right)
que.push(front->right);
}
}
return depth;
}