二叉树:后序遍历非递归算法

分析:后序遍历是三种遍历中最难的一种,后序遍历的特点为左右根,并且也需要借助一个栈来完成,如图,虚线表示p,q最开始的位置,用r指向最近访问过的结点。首先从根节点开始,沿着根的左孩子,将左孩子依次进行入栈。当D入栈之后,由于D没有右孩子,所以将D出栈,此时r指向D。
二叉树:后序遍历非递归算法_第1张图片
D出栈之后读栈顶元素B,p指向B,发现B有右孩子,然后将右孩子E入栈。二叉树:后序遍历非递归算法_第2张图片
然后判断栈顶元素E,E没有右孩子了,所以将E出栈,此时r指向E。
二叉树:后序遍历非递归算法_第3张图片
然后判断栈顶元素B,B的两个孩子都已经操作过了,所以B出栈,p指向A,判断栈顶元素A,A有右孩子,右孩子C入栈,此时r指向C。
二叉树:后序遍历非递归算法_第4张图片
判断栈顶元素C,C无右孩子,所以C出栈,此时栈中只剩A,A的两个孩子都已经操作过了,所以A也出栈,结束,最终后序遍历结果为:DBECA
二叉树:后序遍历非递归算法_第5张图片
算法思想
1、沿着根的左孩子,依次入栈,直到左孩子为空;
2、读栈顶元素进行判定,若右孩子不空且未被访问,将右孩子执行第一步;
3、栈顶元素出栈。
代码

void PostOrder(BiTree){  // 全篇❤
	InitStack(s);
	BiTree *p=T,*r=NULL; // r标记最近访问过的结点
	while(p!=NULL || !IsEmpty(s)){
		if(p!=NULL){
			push(s,p);  // 一直向左走,左孩子入栈
			p=p->lchild;
		}
		else{
			GetTop(s,p);
			// 获取s的栈顶元素赋值给p
			// GetTop(s,p)意思就是判断栈顶元素的情况
			//❤case one❤
			if(p->rchild && p->rchild!=r){
			// 若右孩子存在且未被访问
				p=p->rchild;  // 就让右孩子
				push(s,p)  // 入栈
				p=p->lchild;  // 让右孩子向左
				//上面三句意思就是让右孩子的左孩子一直入栈,一直向左走
			}
			// ❤case two❤
			else{
				pop(s,p);  // 右孩子为空或未被访问过,就出栈
				visit(p->data);
				r=p;  // r标记最近访问结点
				p=NULL;  // r置空
				// 置空原因:因为这个结点已经出栈了
				//继续指向就没必要了,置空后r不标记任何结点
			}
		}
	}
}

你可能感兴趣的:(数据结构,算法,b树,数据结构)