数据结构_二叉树的遍历

先来点题外话:遍历就是按照某种顺序进行访问对应的数据元素。二叉树的遍历是为了访问结点,但是该结点仅且被访问一次。用D,L,R分别表示根结点,左孩子,右孩子,所以这可以组成6中遍历方式,但是我们只看L在R的前面被访问的方式。不是说好的题外话吗???

一、二叉树的递归遍历

1.先序遍历(DLR):先访问根,再是左,最后是右

2.中序遍历(LDR):左,根,右

3.后序遍历(LRD):左,右,根

以上不是说的是递归吗?从何而见它体现了递归呢: 详细解释:比如DLR细化是为:D(DLR)L(DLR)R(DLR),这下明白了吧,递归就是这样体现的。sogo

具体实现:

//先序
void PreOrder(BiTree root)
{
	if(root == NULL)
		return;
	cout<<root->data<<"     ";
	PreOrder(root->lchild);
	PreOrder(root->rchild);
}
//中序
void InOrder(BiTree root)
{
	if(root == NULL)
		return;
	InOrder(root->lchild);
	cout<<root->data<<"   ";
	InOrder(root->rchild);
}
//后序
void PostOrder(BiTree root)
{
	if(root == NULL)
		return;
	PostOrder(root->lchild);
	PostOrder(root->rchild);
        cout<<root->data<<"     ";
}


4.层次遍历:就是从根结点开始,一层层的往下遍历,先遇到的结点先访问。(ps:有点感觉跟排队一样,既然这样就可以用队列(queue)来实现啊!yes,非常正确)

实现方法:首先将根结点入队,然后从队首取出一个元素;具体实现过程如下:

       

void levelOrder(BiTree root)
{
	//用一个一维数组实现队列
	BiTree  queue[100];
	int front = -1, rear = 0;//队首,队尾
	if(root == NULL)
	{
	return;
	}
	//(1)首先将根结点入队
	queue[rear] =  root;
	//当队列为null时,遍历结束
	while (front != rear)
	{
 		front++;//从队首取出一个元素,相当于就是将双亲节点顺序出队

		int returnValue = queue[front]->data;
		//(2)若该元素所指节点的左,右孩子结点非NULL,则将该元素所指结点的左孩子指针和右孩子指针顺序入队
		if(queue[front]->lchild != NULL)
		{
			rear++;
			queue[rear] = queue[front]->lchild;//将队首节点的左孩子入队
		}
		if(queue[front]->rchild != NULL)
		{
			rear++;
			queue[rear] = queue[front]->rchild;
		}

	}
}

二、二叉树遍历的非递归实现

/*
非递归遍历的思想:(1)首先提出两个概念“深入”和“返回”,它们所代表的意思就是“入栈”和“出栈”;为什么这里用栈来表示,因为它们之间的关系是返回时是返回
刚刚压入栈的元素即栈顶元素。(2)深入是从根结点的左孩子开始,当左孩子为null时,将压入的栈顶元素返回,在深入右孩子。
先序遍历的思想:在深入时遇到结点就访问
中序:在左子树返回是访问节点
*/
//先序遍历非递归
void NRPreOrder(BiTree root)
{
	BiTree statck[100];//声明栈
    int top = -1;
    BiTree temp = root;
    if(temp == NULL)
        return;
    while (!(temp ==NULL && top == -1))
    {
        while(temp)
        {
            cout<<temp->data<<"   ";
            top++;
            statck[top] = temp;
            temp = temp->lchild;
        }
        if(top == -1)
            return ;
        else 
        {
            temp = statck[top];
            //中序:在这里访问数据cout<<temp->data<<"   ";
            top--;
            temp = temp->rchild;
        }
    }
}

三、通过遍历序列恢复二叉树

只能通过先序和中序,其次是中序和后序才能确定一个二叉树;

1)已知先序序列和中序序列:首先通过先序确定根结点,然后通过中序确定左右子树,再依次确定相应的节点。


 (2)已知中序和后序:同理可以通过后序序列的最后一个结点找到根结点,然后通过中序分为左右子树,依次递归,便可以得到唯一的二叉树。


 (3)已知先序和后序:这种是不可以的找到唯一的二叉树,因为这种不能唯一确定左右子树。


非递归的二叉树遍历难道只能是通过用栈来实现吗?

no, 常用的不用栈的二叉树非递归遍历方法

1、采用三叉链表

2、采用逆转链表

3、采用线索二叉树的遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值