####二叉树的遍历:
**1,什么是遍历? **
遍历是指对二叉树的每个结点的访问,且只访问一次;
2,遍历规则:
(1)首先,我们知道,二叉树是一颗有序树,有左右子树之分,若给出三个结点(序列号为A,B,C),那么它能够组合成几种二叉树的形态?
上述是根据二叉树的定义(根结点+左子树+右子树)遍历结果,三个结点的二叉树就有这么多的形态,那么对于普通的树就更多了;
//故而,数据结构规定,规在遍历过程中,先遍历左子树,再遍历右子树;故得出三种遍历方式
下面的前,中,后指的是遍历根结点的时机;
3,三种遍历:前序,中序,后序遍历
(1)前序遍历:根结点+左子树+右子树
//1,前序遍历:
void PreOrder(BiTNode *root)
{
if(root)
{
printf("%d ",root->data );
PreOrder(root->lchild );
PreOrder(root->rchild );
}
}
(2)中序遍历:左子树+根结点+右子树
//中序遍历:
void InOrder(BiTNode *root)
{
if(root)
{
InOrder(root->lchild );
printf("%d ",root->data );
InOrder(root->rchild );
}
}
(3)后序遍历:左子树+右子树+根节点
//后序遍历:
void PostOrder(BiTNode *root)
{
if(root)
{
PostOrder(root->lchild );
PostOrder(root->rchild );
printf("%d ",root->data );
}
}
举个例子:
(1)遍历如下二叉树:
(2)遍历过程:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct BinTreeNode
{
int data;
struct BinTreeNode *lchild,*rchild;
}BiTNode,*BiTree;
//1,前序遍历:
void PreOrder(BiTNode *root)
{
if(root)
{
printf("%d ",root->data );
PreOrder(root->lchild );
PreOrder(root->rchild );
}
}
//2,中序遍历:
void InOrder(BiTNode *root)
{
if(root)
{
InOrder(root->lchild );
printf("%d ",root->data );
InOrder(root->rchild );
}
}
//后序遍历:
void PostOrder(BiTNode *root)
{
if(root)
{
PostOrder(root->lchild );
PostOrder(root->rchild );
printf("%d ",root->data );
}
}
int main()
{
BiTNode b1,b2,b3,b4,b5;
memset(&b1,0,sizeof(BiTNode));//将所有的左右结点置为空
memset(&b2,0,sizeof(BiTNode));
memset(&b3,0,sizeof(BiTNode));
memset(&b4,0,sizeof(BiTNode));
memset(&b5,0,sizeof(BiTNode));
b1.data=1;//结点所存放的数据
b2.data=2;
b3.data=3;
b4.data=4;
b5.data=5;
b1.lchild =&b2;//指定结点的左右域指向,建立树
b1.rchild =&b3;
b2.lchild =&b4;
b3.lchild =&b5;
printf("先序遍历的结果是:\n");
PreOrder(&b1);
printf("\n");
printf("中序遍历的结果是:\n");
InOrder(&b1);
printf("\n");
printf("后序遍历的结果是:\n");
PostOrder(&b1);
printf("\n");
return 0;
}
(3)遍历实现结果:
我们可以看出,程序的实现结果和我们预期的一样
(4)遍历的本质:
如果将输出语句printf去掉之后,从递归上看,这三种算法完全一样:
void TOrder(BiTNode *root)
{
if(root)
{
TOrder(root->lchild );
TOrder(root->rchild );
}
}
或者说:三种遍历的访问路径是相同的,只是访问结点的时机的不同;
特别说明:如图所示,从虚线出发到终点的路径上,每个结点经过三次
第一次:前序遍历
第二次:中序遍历
第三次:后序遍历
(5)时间复杂度和空间复杂度:
1〉时间复杂度为:O(n)
//每个结点只访问一次
2〉空间复杂度为:O(n)
//栈占用的最大辅助空间