最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

二叉树的遍历

XAMPP相关 admin 461浏览 0评论

drc61

1. 先序(根)遍历(preorder traversal)

(1)访问根结点

(2)先序遍历左子树

(3)先序遍历右子树

例如,上图所示的二叉树的先序序列为ABDGCEF。

显然,在一棵二叉树的先序序列中,第一个元素即为根结点对应的结点值。

 

2. 中序遍历(inorder traversal)

(1)中序遍历左子树

(2)访问根结点

(3)中序遍历右子树

例如,上图所示的二叉树的中序序列为DGBAECF。

显然,在一棵二叉树的中序序列中,根结点值将其序列分为前、后两个部分,前部分为左子树的中序序列,后部分为右子树的中序序列。

 

3. 后序(根)遍历(postorder traversal)

(1)后序遍历左子树

(2)后序遍历右子树

(3)访问根结点

例如,上图所示的二叉树的后序序列为GDBEFCA。

显然,在一棵二叉树的后序序列中,最后一个元素即为根结点对应的结点值。

 

4. 层次遍历(level traversal)

是非递归的,用于一层一层地访问二叉树中的所有结点。其过程如下:

若二叉树非空(假设其高度为h),则:

(1)访问根结点(第1层)

(2)从左到右访问第2层的所有结点

(3)从左到右访问第3层的所有结点,……,第h层的所有结点。

例如,上图所示的二叉树的层次遍历序列为ABCDEFG。

显然,在一棵二叉树的层次遍历序列中,第一个元素即为根结点对应的结点值。

 

5. 算法实现

先序、中序、后序遍历的递归算法

//先序遍历的递归算法
void PreOrder(BTNode *b)
{
if(b != NULL)
    {
printf("%c ", b->data);  //访问跟结点
        PreOrder(b->lchild);    //先序遍历左子树
        PreOrder(b->rchild);    //先序遍历右子树
    }
}

//中序遍历的递归算法
void InOrder(BTNode *b)
{
if(b != NULL)
    {
        InOrder(b->lchild); //中序遍历左子树
printf("%c ", b->data);
        InOrder(b->rchild); //中序遍历右子树
    }
}

//后序遍历的递归算法
void PostOrder(BTNode *b)
{
if(b != NULL)
    {
        PostOrder(b->lchild);   //后序遍历左子树
        PostOrder(b->rchild);   //后序遍历右子树
printf("%c ", b->data);
    }
}

先序遍历非递归算法

typedef struct
{
    BTNode *data[MaxSize];
int top;
}SqStack;
//非递归实现先序遍历1
void PreOrder1(BTNode *b)
{
    BTNode *p;
    SqStack *st;    //定义栈指针
    InitStack(st);  //初始化栈
if(b != NULL)
    {
        Push(st, b);    //根节点进栈
while (!StackEmpty(st)) 
        {
            Pop(st, p); //退根节点p并访问它
printf("%c", p->data);
if (p->rchild != NULL)  //有右孩子时将其进栈
                Push (st, p->rchild);
if (p->lchild != NULL)  //有左孩子时将其进栈
                Push (st, p->lchild);
        }
printf("    ");
    }
 
   DestroyStack (st);  //销毁栈
}

//非递归实现先序遍历2
void PreOrder2(BTNode *b)
{
    BTNode *p;
    SqStack *st;
    InitStack (st);
    p = b;
while (!StackEmpty(st) || p != NULL)
    {
while (p != NULL)   //访问结点p及其所有左下结点并进栈
        {
printf ("%c", p->data);
            Push (st, p);
            p = p->lchild;
        }
if (!StackEmpty(st))    //
        {
            Pop (st, p);    //出栈p
            p = p->rchild;  //转向处理其右子树
        }
    }
printf ("   ");
    DestroyStack (st);
}

中序遍历非递归算法

//中序遍历的非递归算法
void InOrder1(BTNode *b)
{
BTNode *p;
SqStack *st;
InitStack (st);
p = b;
while (!StackEmpty (st) || p != NULL)
{
while (p != NULL)   //扫描结点p的所有坐下结点并进栈
{
Push (st, p);
p = p->lchild;
}
if (!StackEmpty (st))   
{
Pop (st, p);
printf ("%c", p->data);
p = p->rchild;  //转向处理其右孩子结点
}
}
printf ("   ");
DestroyStack (st);
}

后序遍历非递归算法

//后序遍历的非递归算法
void PostOrder1(BTNode *b)
{
    BTNode *p, *r;
bool flag;
    SqStack *st;
    InitStack (st);
    p = b;
do
    {
while (p != NULL)   //扫面结点p的所有左下结点并进栈
        {
            Push (st, p);
            p = p->lchild;  //移动到左孩子
        }
        r = NULL;   //r指向刚访问的结点,初始时为空
        flag = true;    //flag为真表示正在处理栈顶结点
while  (!StackEmpty (st) && flag)
        {
            GetTop (st, p);
if (p->rchild == r) //若结点p的右孩子为空或者为刚刚访问的结点
            {
printf ("%c", p->data);
                Pop (st, p);
                r = p;  //r指向刚刚访问的结点
            }
else
            {
                p = p->rchild;  //转向处理其右子树
                flag = false;   //表示当前不是处理栈顶结点
            }
        }

    }
while (!StackEmpty (st));   //栈不空循环
printf ("   ");
    DestroyStack (st);
}

层次遍历

//层次遍历
typedef struct
{
    BTNode *data[MaxSize];
int front, rear;
}SqQueue;   //顺序队类型

void LevelOrder(BTNode *b)
{
    BTNode *p;
    SqQueue *qu;    //定义 环形队列 指针
    InitQueue (qu);
    enQueue (qu, b);    //根节点指针进队
while (!QueueEmpty (qu))
    {
        deQueue (qu, p);    //出队结点p
printf ("%c", p->data);
if (p->lchild != NULL)  //有左孩子时将其进队
            enQueue (qu, p->lchild);
if (p->rchild != NULL)  //有右孩子时将其进队
            enQueue (qu, p->rchild);
    }
}

 

转载请注明:XAMPP中文组官网 » 二叉树的遍历

您必须 登录 才能发表评论!