5.3二叉树的遍历和线索树

5.3.1二叉树的遍历

二叉树的遍历是指按某条探索路径访问树的每个节点,使每个节点均被访问一次,且仅被访问一次

二叉树-->遍历次序

常见遍历次序

最坏的情况下,二叉树有n个节点且深度为n的单支树,空间复杂度为O(n)

先中后序遍历手算展开

1.先序遍历

先访问根节点,先序遍历左子树,先序遍历右子树

第一次路过时就访问--一个箭头指向时

void preOrder(linklist t) {
	visit(t);//访问根节点
	preOrder(t->lChild);//递归遍历左子树
	preOrder(t->rChild);//递归遍历右子树
}

2.中序遍历

中序遍历左子树,访问根节点,中序遍历右子树

第二次路过时就访问--两个箭头指向时

//中序遍历
void preOrder(linklist t) {
	preOrder(t->lChild);//递归遍历左子树
	visit(t);//访问根节点
	preOrder(t->rChild);//递归遍历右子树
}

3.后序遍历

后序访问左子树,后序访问右子树,访问根节点

第三次路过时就访问--三个箭头指向时

//后序遍历
void preOrder(linklist t) {
	preOrder(t->lChild);//递归遍历左子树
	preOrder(t->rChild);//递归遍历右子树
	visit(t);//访问根节点
}

层次遍历

自上而下,从左至右遍历

遍历思想:(王道p47  1.22m)

①现将二叉树根节点入队

②若队列非空,则队头节点出队,访问该节点,若有左孩子,则将左孩子入队;若有右孩子则将右孩子入队;

③重复②步,直至该队列为空

算法

void LevelOrder(linklist t) {
	initqueue(s);//初始化队列
	linklist p;
	enqueue(s, t);//将根节点入队
	while (!isempty(s))//判断队列是否为空
	{
		//不为空则输出节点
		//访问其左孩子,右孩子,并将其入队
		dequeue(s,p);
		visit(p);//访问出队节点
		if (p->lChild!=NULL)
		{
			enqueue(s, p->lChild);
		}
		if (p->rChild!=NULL)
		{
			enqueue(s, p->rChild);
		}
	}
	
}

由遍历序列构造二叉树(遍历序列->二叉树)

※找到树的根节点,并根据中序序列划分左右子树,在找到左右子树根节点

  1. 中序+前序
  2. 中序+后序
  3. 中序+层次

5.3.2线索二叉树

线索二叉树基本概念

二叉树的线索化是将二叉树链表中的空指针改为前驱或后继节点的线索.

线索二叉树节点结构

若无左孩子,则lchild指向前驱节点;若无右孩子,则rchild指向后继节点

标志域ltag=0则lchild指向左孩子;ltag=1则lchild指向前驱节点

中序线索二叉树

步骤

算法实现

#include<stdio.h>;
typedef struct BiTree
{
	int data;
	BiTree* rchild;
	BiTree* lchild;
	int ltag;
	int rtag;
}BiTree,*linklist;
linklist pre = NULL;
//中序遍历
void inThread(linklist& p) {
	inThread(p->lchild);
	visit(p);
	inThread(p->rchild);
}
void visit(linklist &p) {
	if (p->lchild == NULL) {
		p->lchild = pre;
		p->ltag = 1;
	}
	if (pre != NULL && p->rchild == NULL) {

		pre->rchild = p;
		pre->rtag = 1;
	}
	pre = p;
}
void createInThread(linklist &p) {
	if (p != NULL) {
		inThread(p);
		if (pre->rchild==NULL)
		{
			pre->rtag = 1;
		}
     
	}

}

前序线索二叉树

算法实现

//前序遍历
void inThread(linklist& p) {
	visit(p);
	if (p->ltag==0)
	{
	inThread(p->lchild);
	}
	inThread(p->rchild);
}
void visit(linklist& p) {
	if (p->lchild == NULL) {
		p->lchild = pre;
		p->ltag = 1;
	}
	if (pre != NULL && p->rchild == NULL) {

		pre->rchild = p;
		pre->rtag = 1;
	}
	pre = p;
}
void createInThread(linklist& p) {
	if (p != NULL) {
		inThread(p);
		if (pre->rchild == NULL)
		{
			pre->rtag = 1;
		}

	}

}

后序线索二叉树

算法实现


//后序遍历
void inThread(linklist& p) {
	inThread(p->lchild);
	inThread(p->rchild);
	visit(p);
}
void visit(linklist& p) {
	if (p->lchild == NULL) {
		p->lchild = pre;
		p->ltag = 1;
	}
	if (pre != NULL && p->rchild == NULL) {

		pre->rchild = p;
		pre->rtag = 1;
	}
	pre = p;
}
void createInThread(linklist& p) {
	if (p != NULL) {
		inThread(p);
		if (pre->rchild == NULL)
		{
			pre->rtag = 1;
		}

	}

}

线索二叉树找前驱,后继

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值