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

二叉树(BiTree)的遍历分为:
先序遍历(preorder):根左右
中序遍历(inorder):左根右
后序遍历(postorder):左右根
其中,时间复杂度和空间复杂度都是O(n),
二叉树的遍历递归算法不常考,主要考察非递归❤

先序、中序、后序遍历(递归)

递归算法的区别在于visit()函数的位置❤,代码以先序遍历为例,其顺序为根左右,if判断语句中符合这一规律,中序、后序按其左根右和左右根的规律改变这三句代码的顺序即可。

void preorder(BiTree T){ // 先序遍历递归算法
	if(T!=NULL){  // 当二叉树的根节点不为空时
		visit(T); // 先访问根节点❤
		preorder(T->lchild); // 再访问左孩子
		preorder(T->rchild);  // 最后访问右孩子
	}
}

中序遍历(非递归)

算法思想:非递归需要借助栈来实现,沿着根的左孩子一直向左走,将左孩子依次入栈,直到左孩子为空,然后从栈顶开始出栈,出栈的同时访问出栈结点,若有右孩子则等该出栈元素出栈后把他的右孩子入栈。
图解与分析
p指向根节点,q指向栈底
二叉树:中序遍历非递归与递归算法_第1张图片
然后沿着左孩子一直走,并依次入栈,当走到D结点时,没有左孩子了。这时开始从栈顶出栈,此时的遍历序列为D,B。
二叉树:中序遍历非递归与递归算法_第2张图片
D,B出栈后,此时p指向B结点,发现B还有右孩子,所以将右孩子出栈。此时的序列为D,B,E,此时栈里只剩一个A结点了。
二叉树:中序遍历非递归与递归算法_第3张图片
然后继续将栈顶元素进行出栈并访问,此时序列为D,B,E,A,此时p指向A结点,发现A结点有右孩子,将右孩子进栈并出栈。此时二叉树遍历完毕,栈也为空,最终中序遍历结果为:DBEAC。
二叉树:中序遍历非递归与递归算法_第4张图片
代码

void Inorder(BiTree T){
	InitStack(s); // 初始化一个栈s
	BiTree *p=T;  // 将二叉树的根节点赋给指针p
	while(p!=NULL || !IsEmpty(s)){ 
	//❤ 二叉树不为空或栈不为空
	// 即二叉树遍历完了栈也为空,才是真正的遍历完了,要不就像上面最后一张图,
	// 栈空了,C还没进栈呢,就退出循环了。
		if(p!=NULL){
			push(s,p); // 左孩子依次,入栈
			p=p->lchild;  // 左孩子不为空,向左一直走
		}
		else{
			pop(s,p);  // 栈顶元素,出栈 
			visit(p);
			p=p->rchild;  // 访问右子树
		}
	}
	free(s); 
}

注解
push(s,x) 表示x入栈
pop(s,y) 表示y出栈
IsEmpty(A) 表示判断数列是否为空的函数
InitStack(s) 表示初始化栈s

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