【树的遍历】

本文详细介绍了四种二叉树遍历方法:先序遍历、中序遍历、后序遍历和层序遍历的实现,以及树的宽度、深度的计算。此外,还探讨了孩子兄弟表示法下树的高度计算和叶子节点数量的求解,并提供了交换二叉树左右子树的算法。
摘要由CSDN通过智能技术生成

先序遍历
如果树不空
{
建栈,根节点入栈,只要栈不空
{借助p出栈栈顶元素并访问,如果右孩子存在右孩子入栈,左孩子存在左孩子入栈}
}

void preorder(BTNode *bt)
{
	if(bt!=NULL)
	{
		BTNode *Stack[maxsize];
		int top=-1;//定义并初始化一个栈
		BTNode *p;//遍历指针 
		Stack(++top)=bt;
		while(top!=-1)
		{
			p=Stack[top--];
			printf("%d",p->data);//出栈并访问栈顶结点
			if(p->rchild!=NULL)
				Stack[++top]=p->rchild;
			if(p->lchild!=NULL)
				Stack[++top]=p->lchild;				
		}
	}
}

中序遍历
借助遍历指针p,p指向根节点,只要栈不空或p不空:
{
只要p不空:{p入栈并左移}
只要栈不空{出栈并输出栈顶结点,p右移}
}

void inorder(BTNode *bt)
{
	if(bt!=NULL)
	BTNode *Stack[maxsize];
	int top=-1;
	BTNode *p;//遍历指针
	p=bt;
	while(top!=-1||p!=NULL)
	{
		while(p!=NULL)//左孩子存在,左孩子入栈
		{
			Stack[++top]=p;
			p=p->lchild;
		}
		//左孩子不存在,
		if(top!=-1)//栈不空,出栈并输出栈顶元素,右孩子入栈
		{
			p=Stack[top--];
			printf("%d",p->data);
			p=p->rchild;
		}
	}
}

后序遍历
如果树不空:
{
建2个栈,根节点入栈1
只要栈1不空:
{从栈1出栈入栈2,左孩子不空左孩子入栈1,右孩子不空右孩子入栈1;}
只要栈2不空:
{出栈并输出栈顶元素}
}

void postorder(BTNode *bt)
{
	if(bt!=NULL)
	{
		BTNode *Stack1[maxsize];
		BTNode *Stack2[maxsize];
		int top1=-1;
		int top2=-1;
		BTNode *p=NULL;//用于接收从栈1出栈的元素
		Stack[++top1]=bt;
		while(top1!=-1)   //只要栈1不空
		{
			p=Stack1[top1--];  //p从栈1出栈入栈2
			Stack[++top2]=p;
			if(p->lchild!=NULL)//左孩子不空 左孩子入栈
				Stack1[++top1]=p->lchild;
			if(p->rchild!=NULL)  //右孩子不空,右孩子入栈
					Stack1[++top1]=p->rchild;
		}
		while(top2!=-1)    //只要栈2不空,出栈并输出栈顶元素
		{
			p=Stack2[top2--];
			printf("%d",&p->data);
		}
	}
}

层序遍历
建队,如果树不空
{
根节点入队,只要队不空{利用q出队队头元素,左、右孩子入队

void level(BTNode *p)
{
	int front,rear;
	BTNode *que[maxsize];//设置一个队列
	front=rear=0;//队列初始化
	BTNode *q;//遍历指针
	if(p!=NULL)
	{
		rear=(rear+1)%maxsize;
		que[rear]=p;//根节点入队
		while(front!=rear)
		{
			front=(front+1)%maxsize;
			q=que[front];//队头结点出队
			if(q->lchild!=NULL)
			{
				rear=(rear+1)%maxsize;
				que[rear]=q->lchild;
			}
			if(q->rchild=NULL)
			{
				rear=(rear+1)%maxsize;
				que[rear]=q->rchild;
			}
		}		
	}
}

自下而上、自左至右层次遍历
设置队列和栈,根节点入队,队列不空时Q出队,出队元素入栈S,其左右非空子女入队,队列空后,弹出栈S

void level(BiTree *T)
{
	BiTree Q[MAXSIZE];
	int front=-1,rear=-1;
	BiTree S[MAXSIZE];
	int top=-1;
	Q[++rear]=T;
	while(front!=rear)
	{
		p=S.[++front];
		S[++top]=p;
		if(p->lchild)
			Q[++rear]=p->lchild;
		if(p->rchild)
			Q[++rear]=p->rchild;
	}
	while(top!=-1)
	{
		q=S[top--];
	}
}

树的宽度

typedef struct
{
	BTNode data[maxsize];
	int level[maxsize];//保存data中相同下标结点的层次
	int front,rear;
}Qu;
int getWidth(BTNode b)
{
	BTNode p;
	int k,max,i,n;
	Qu.front=Qu.rear=-1;//队列置空
	Qu.data[Qu.rear]=b;//根节点入队
	Qu.level[Qu,rear]=1;//根节点所在层次为1
	while(Qu.front<Qu.rear)//队不空
	{
		p=Qu.data[++Qu.front];//出队
		k=Qu.level[Qu.front];//出队节点所在层次
		if(p->lchild!=NULL)
		{
			Qu.data[++Qu.rear]=p->lchild;//下一层节点入队
			Qu.level[Qu.rear]=k+1;//尾结点所在层次加1
		}
		if(p->rchild!=NULL)
		{
			Qu.data[++Qu.rear]=p->rchild;
			Qu.level[Qu.rear]=k+1;
		}
	}
	max=0;//保存同一层最多的结点个数
	i=0;//i扫描队中所有元素
	k=1;//从第一层开始找
	while(i<=Qu.rear)
	{
		n=0;
		while(i<=Qu.rear&&Qu.level[i]==k)
		{
			n++;
			i++;
		}
		k=Qu.level[i];
		if(n>max)
			max=n;
	}
	return max;
}

树的深度
设置队列 设置last指向下一层(初始化为0) 设置level(初始化为0)
根节点入队 只要队列不空:队头元素出队 如果出队元素左孩子不空左孩子入队 右孩子不空右孩子入队 如果(front==last)则 level++,last=rear;

int getdepth(BTNode T)
{
	int depth,depthl,depthr;
	if(T==NULL)
		depth=0;
	else
	{
		depthl=getdepth(T->lchild);
		depthr=getdepth(T->rchild);
		depth=1+(depthl>depthr?depthl:depthr);	
	}
	return depth;
}

int depth(BTNode T)
{
	if(!T)
		return 0;
	int front=-1;//指向队头元素
	int rear=-1;//rear指向队尾元素
	int last=0;//指向下一层 当出队到last时 表示last所在层数被访问到
	int level=0;
	BTNode Q[maxsize];
	Q[++rear]=T;
	BTNode p;
	while(front!=rear)//队列不空
	{	
		p=Q[++front];//队头元素出队
		if(p->lchild)
			Q[++rear]=Q->lchild;
		if(p->rchild)
			Q[++rear]=Q->rchild;//
		if(front==last)//该层最后一个节点出队后level+1
		{
			level++;
			last=rear;//last指向该层最后一个节点  
		}				
	}	
}

孩子兄弟表示法求树的高度
树为空高度为0,孩子节点为空 高度为最大兄弟子树的高度+1
否则高度为max{1+孩子子树高度,兄弟子树高度}

typdef struct
{
	int data;
	BTNode *child;
	BTNode *sibling;
}BTNode;

void height(BTNode *bt)
{
	if(bt==NULL)
		 return 0;
	else if(!bt->child)
		return max(1,height(bt->sibling));
	else
	{
		hc=height(bt->child);
		hs=height(bt->sibling);
		if(hc+1>hs)
			return hc+1;
		else return hs;
}
}

求双亲表示法求二叉树叶子节点个数

typedef struct BTNode
{
	int data;
	struct BTNode *lchild;
	strcut BTNode *rchild;
}BTNode;

int count(BTNode *bt)
{
	int count=0;
	if(bt==NULL)
		return 0;
	else if(bt->lchild==NULL&&bt->rchild==NULL)
		count=1;
	else
	{
		return count(bt->lchild)+count(bt->rchild);
	}
	return count;
}

孩子兄弟表示法求树的叶子节点个数

typedef struct BTNode
{
	int data;
	struct BTNode *ch;
	struct BTNode *sbl;
}BTNode;
int leaf(BTNode *T)
{
	if(T==NULL)
		return 0;
	if(T->ch==NULL)
		return 1+leaf(T->sbl);
	else
		return leaf(T->ch)+leaf(T->sbl);
}

将二叉树中所有左右子树相互交换
设置栈 根节点入栈 只要栈不为空:出栈栈顶元素,如果出栈元素不是叶子节点 则利用中间变量进行交换 如果左孩子不空,左孩子入栈,右孩子不空,右孩子入栈

void swap(BiTree &T)
{
	BiTree *p;
	if(T)
	{
		swap(T->lchild);
		swap(T->rchild);
		p=T->lchild;
		T->lchild=T->rchild;
		T->rchild=p;
	}
}
void swap(BiTree T)
{
	BiTree S[MAXSIZE];
	int top=-1;
	S[++top]=T;
	while(top!=-1)
	{
		p=S[top--];//出栈栈顶元素
		if(p->lchild||p->rchild)//非叶子节点 交换左右子树
		{
			q=p=>lchild;
			p->lchild=p->rchild;
			p->rchild=q;
			}
		if(p->lchild) //左孩子入栈
			s[++top]=p->lchild;
		if(p->rchild) //右孩子入栈
			s[++top]=p->rchild;
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值