树的三种遍历

二叉树的先序遍历(递归)

遍历顺序:

         1.先访问根节点
         2.左子树递归调用先序遍历
         3.右子树递归调用先序遍历

图示:

  • 分析:1.输出根节点A,2.递归左子树,输出左子树的根节点B,继续遍历左边输出C,然后右边输出F,然后输出E
    3.递归右子树,输出右子树的根节点C,访问左边,输出G,G的左边没了,右边输出H,C的左边遍历完了,右边输出I。

代码:

void PreOrder(BinTree BT)
{
	if(BT){//如果树不为空
		cout<<BT->Data;//输出根节点(先序遍历:输出结点代码在递归之前)
		PreOrder(BT->Left);//递归左子树
		PreOrder(BT->Left);//递归右子树
	}
}

结果:

      - A (BDFE) (CGHI)

二叉树的中序遍历(递归)

遍历顺序:

                    1.中序遍历其左子树(递归调用)
                    2.访问根节点
                    3.中序遍历其右子树(递归调用)

图示:

  • 分析:1.先访问左子树,走到底(左边没元素了),输出当前结点D,往回走,输出B,遍历B的右子树,到底输出E,然后F。2.此时A的左子树遍历完了,输出A。
    3. 接着遍历其右子树,走左边到底,输出H,再G,此时C的左边走完了,输出C,接着遍历C的右边,输出I。
  • ps:中序遍历的结果是整棵树的投影

代码:

void PreOrder(BinTree BT)
{
	if(BT){//如果树不为空
		PreOrder(BT->Left);//递归左子树
		cout<<BT->Data;//输出节点(中序遍历:输出结点的代码在递归中间)
		PreOrder(BT->Left);//递归右子树
	}
}

结果:

      -(DBEF)A (GHCI)

二叉树的后序遍历(递归)

遍历顺序:

                    1.后序遍历其左子树(递归)
                    2.后序遍历其右子树(递归)
                    3.访问根节点

图示:

  • 分析:1.遍历左子树,走到底,输出D,回到B遍历右,到E,输出E,输出F,输出B,遍历A的右,遍历C的左,输出H,输出G,遍历C的右输出I,在输出C,最后输出根节点A

代码:

void PreOrder(BinTree BT)
{
	if(BT){//如果树不为空
		PreOrder(BT->Left);//递归左子树
		PreOrder(BT->Left);//递归右子树
		cout<<BT->Data;//输出节点(后序遍历:输出结点代码在递归之后)
	}
}

结果:

      - (DEFB) (HGIC) A

总结:

  • 不同主要在于输出语句的位置。

中序遍历的堆栈实现(非递归)

遍历实现:

     1.遇到一个结点,压入栈,并遍历左子树
     2.遍历完左子树,栈顶弹出一个元素
     3.对弹出元素再遍历其右子树

实现过程:

  • 首先,把根节点A入栈,访问左子树,B入栈,访问B的左子树,D,此时到底了,弹出栈顶元素D,B的左子树遍历完成,输出B,遍历B的右子树,F入栈,E入栈,E出,

代码:

void InOrder(BinTree BT) 
{
	BinTree T;
	Stack S = CreatStack(MaxSize);//建立并初始化栈
	while (T || !IsEmpty(S)) {//判断栈为空否
		while (T) {
			Push(S, T);//进栈
			T = T->Left;//转到左子树遍历
		}
		if (!IsEmpty(S)) {
			T = Pop(S);//出栈
			cout << T->Data;//输出
			T = T->Right;//转到右子树遍历
		}
	}
}
  • ps: 前序遍历则只需把输出语句放在Push()前

  • ps: 后序遍历则需要将节点俩次入栈,第二次Pop时再输出,有点复杂,未做深入研究

层次遍历的队列实现

  • 层次遍历:一层一层的遍历

遍历顺序:

          1.根节点入队
      2.出队队首元素
      3.把出队元素的左右孩子依次入队

代码:


void LeveOrder(BinTree BT)
{
	Queue Q;
	BinTree T;
	if (!BT) return;//若树为空,直接返回
	Q = CreatQueue(MaxSize);//创建并初始化队列Q
	AddQ(Q, BT);//加入根节点
	while (!IsEmptyQ(Q)) {
		T = DeleteQ(Q);//出队操作
		cout << T->Data;
		if (T->Left)
			AddQ(Q, T->Left);//加入左孩子
		if (T->Right)
			AddQ(Q, T->Right);//加入右孩子
	}
}

结果:

      - A BC DFGI EH

两种遍历确定唯一的二叉树(必须含中序遍历)

  • 若已知先序遍历顺序为:a bcdefghij和中序遍历顺序为:cbed a hgijf

求解思路:

        1.根据先序第一个节点,确定根节点
        2.在中序中找到a,a左边的就是左子树,右边的为右子树
        3.依次对左右子树递归可确定出最后的树
原文地址:https://www.cnblogs.com/lushuang55/p/13882053.html