数据结构二叉树的遍历

数据结构二叉树的遍历

二叉树的遍历有先序,中序,后序,层序法.

其中创建二叉树用了先序递归的方法创建,后序遍历也是用递归实现的,中序遍历是通过调用一些栈的函数来实现的(其实递归函数的时候就是以栈的形式展开的);层序遍历则通过调用一些队列的函数来实现.

以下是一些头文件:

#include "BinaryTree.h"
#include "queue.h"
#include "stack.h"

#incline "BinaryTree.h"的头文件代码如下:

#pragma once
#ifndef BINARYTREE_H_
#define BINARYTREE_H_
#include "stdafx.h"
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef char TElemType;
typedef struct BiTNode    //二叉树结点
{
    TElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

Status Visit(TElemType e);
Status CreateBiTree(BiTree &T);
Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e));
Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e));
Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e));
Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType e));
#endif

#incline "queue.h"的头文件代码如下:

#pragma once
#ifndef QUEUE_H_
#define QUEUE_H_
#include "stdafx.h"
#include "BinaryTree.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
typedef BiTree QElemType;
typedef int Status;
typedef struct QNode
{
    QElemType data;
    struct QNode *next;
}QNode, *QueuePtr;
typedef struct
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

Status InitQueue(LinkQueue &Q);
Status QueueEmpty(LinkQueue Q);
Status EnQueue(LinkQueue &Q, QElemType e);
Status DeQueue(LinkQueue &Q, QElemType &e);
#endif

#incline "stack.h"的头文件代码如下:

#pragma once
#ifndef STACK_H_
#define STACK_H_
#include "stdafx.h"
#include "BinaryTree.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
typedef BiTree SElemType;
typedef int Status;
typedef struct SNode
{
    SElemType data;
    struct SNode *next;
}SNode, *StackPtr;
typedef struct
{
    StackPtr base;
    StackPtr top;
}LinkStack;

Status InitStack(LinkStack &S);
Status Push(LinkStack &S, SElemType e);
Status Pop(LinkStack &S, SElemType &e);
BiTree GetTop(LinkStack S, SElemType &e);
bool StackEmpty(LinkStack S);
#endif

以下是一些源文件:

#include "BinaryTree.cpp"
#include "queue.cpp"
#include "stack.cpp"

#incline "BinaryTree.cpp"的源文件代码如下:

#include "stdafx.h"
#include "BinaryTree.h"
#include "stack.h"
#include "queue.h"
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;

Status Visit(TElemType e)
{//Visit函数
     cout << e<<" ";
    return OK;
}

Status CreateBiTree(BiTree &T)
{//按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树
    TElemType ch;
    cin >> ch;
    if (ch == '0') T = NULL;
    else
    {
        if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))  exit(OVERFLOW);
        T->data = ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
    return OK;
}

Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e))
{//先序遍历二叉树T的递归算法
    if (T)
    {
        if (Visit(T->data))
        {
            if (PreOrderTraverse(T->lchild, Visit));
            {
                if (PreOrderTraverse(T->rchild, Visit));   return OK;
            }
        }
        return ERROR;
    }
    else
        return OK;
}

Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e))
{//中序遍历二叉树T引用栈的算法
    BiTree p;
    LinkStack S;
    InitStack(S); p = T;
    while (p || !StackEmpty(S))
    {
        if (p) { Push(S, p); p = p->lchild; }
        else
        {
            Pop(S, p);   if (!Visit(p->data))   return ERROR;
            p = p->rchild;
        }
    }
    return OK;
}

Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e))
{//后序遍历二叉树T的递归算法
    if (T) /* T不空 */
    {
        PostOrderTraverse(T->lchild, Visit); //先后序遍历左子树 
        PostOrderTraverse(T->rchild, Visit); //再后序遍历右子树 
        Visit(T->data);                      //最后访问根结点 
    }
    return OK;
}

Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{//层序遍历二叉树T的引入队列的算法
    BiTree e ;
    LinkQueue Q ;
    if (T)
    {
        InitQueue(Q);
        EnQueue(Q, T);          //根指针进队列
        while (!QueueEmpty(Q))
        {
            DeQueue(Q, e);      //根指针出队
            Visit(e->data);     //读取根指针元素
            if (e->lchild != NULL)
                EnQueue(Q, e->lchild);
            if (e->rchild != NULL)
                EnQueue(Q, e->rchild);
        }
        cout << "\n";
    }
    return OK;
}

#incline "queue.cpp"的源文件代码如下:

#include "stdafx.h"
#include "queue.h"
#include <stdlib.h>

Status InitQueue(LinkQueue &Q)
{//初始化队列
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
    if (!Q.front) exit(OVERFLOW);
    Q.front->next = NULL;
    return OK;
}
Status QueueEmpty(LinkQueue Q)
{
    if (Q.front == Q.rear)
        return TRUE;
    else
        return FALSE;
}
Status EnQueue(LinkQueue &Q, QElemType e)
{ /* 插入元素e为Q的新的队尾元素 */
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) /* 存储分配失败 */
        exit(OVERFLOW);
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
}
Status DeQueue(LinkQueue &Q, QElemType &e)
{ /* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
    QueuePtr p;
    if (Q.front == Q.rear)
        return ERROR;
    p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p)
        Q.rear = Q.front;
    free(p);
    return OK;
}

#incline "stack.cpp"的源文件代码如下:

#include "stdafx.h"
#include "stack.h"
#include "BinaryTree.h"
#include <stdlib.h>

Status InitStack(LinkStack &S)
{//栈的初始化
    S.top = S.base = (StackPtr)malloc(sizeof(SNode));
    if (!S.top) exit(OVERFLOW);
    S.top->next = NULL;
    return OK;
}

Status Push(LinkStack &S, SElemType e)
{//插入元素e为新的栈顶元素
    StackPtr p;
    p = (StackPtr)malloc(sizeof(SNode));
    p->data = e; p->next = NULL;
    S.top->next = p;
    S.top = p;
    return OK;
}

Status Pop(LinkStack &S, SElemType &e)
{//删除栈顶元素
    StackPtr p, q;

    p = S.base->next;
    q = S.base; // 前一个
    while (p->next)
    {
        p = p->next;
        q = q->next; // 前一个
    }
    e = p->data;
    q->next = NULL;
    S.top = q;
    free(p);
    return OK;
}

BiTree GetTop(LinkStack S, SElemType &e)
{
    e = S.top->data;
    return e;
}

bool StackEmpty(LinkStack S)
{//判断空
    if (S.base == S.top) return true;
    else
        return false;
}

以下是一些测试函数的代码:

#include "stdafx.h"
#include "BinaryTree.h"
#include "stack.h"
#include "queue.h"
#include 
using namespace std;
int main()
{
    BiTree T;
    cout << "创建二叉树!" << endl;
    CreateBiTree(T);

    cout << "先序遍历二叉树如下:" << endl;
    PreOrderTraverse(T,Visit);
    printf("\n");

    cout << "中序遍历二叉树如下:" << endl;
    InOrderTraverse(T, Visit);
    cout<<"\n";

    cout << "后序遍历二叉树如下:" << endl;
    PostOrderTraverse(T, Visit);
    cout << endl;

    cout << "层序遍历二叉树如下:" << endl;
    LevelOrderTraverse(T, Visit);
    cout << endl;

    return 0;
}

以下是运行截图:

数据结构二叉树的遍历_第1张图片

以上这些就是我参考了参考书和网上的算法后自己整理归纳写的二叉树遍历算法,这些算法如果有不足或者可以改进的地方,希望大家指出!

你可能感兴趣的:(C++编程)