数据结构---二叉树遍历(递归与非递归)

二叉树的定义

二叉树(Binary Tree) 是n(n>=0)个节点的有限集合,该集合或者为空(称为空二叉树),或者由一个根节点和两颗互不相交的、分别称为根节点的左子树和右子树的二叉树组成 —— 《大话数据结构 》

数据结构---二叉树遍历(递归与非递归)_第1张图片
二叉树的特点:

1、每个节点最多有两颗子树,所以二叉树中不存在度大于2的节点。
2、左子树和右子树是有顺序的,次数不能任意颠倒。
3、即使树中某节点只有一颗子树,也要区分是左子树还是右子树。

本文主要针对二叉树的递归和非递归进行编程实现,代码如下:

//---二叉树遍历----  
//-作者:KWJ
//-时间:20171230#include  
#include  
#include
#include   
#include 
#define maxlen 20
using  namespace std;

typedef char ElemType;         // 二叉树结点元素类型  
typedef struct BiTNode{        // 二叉树结点结构  
    char data;                 // 结点数据  
    struct BiTNode *lchild;    // 左孩子  
    struct BiTNode *rchild;    // 右孩子  
}BiTNode, *BiTree;
//--定义队列,用于实现层次遍历--

typedef struct qnode
{
    BiTNode *data[maxlen];
    int front, rear;
}queue;                       // 队列数据类型

/*----------------------------代码实现---------------------------------*/
//前序遍历:根节点->左子树->右子树
//中序遍历:左子树->根节点->右子树
//后序遍历:左子树->右子树->根节点

//--构建一颗树--
BiTree CreateBiTree(BiTree T)
{
    char ch;
    scanf_s("%c", &ch);
    if (ch == '#')
        T = NULL;
    else
    {
        if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))
            exit(OVERFLOW);
        T->data = ch;                           // 生成根节点       
        T->lchild = CreateBiTree(T->lchild);    // 构造左子树  
        T->rchild = CreateBiTree(T->rchild);    // 构造右子树  
    }
    return T;
}
//--先序遍历递归算法--  
void PreOrderRecursionTraverse(BiTree T)
{
    if (T == NULL)
        return;
    printf("%c", T->data);
    PreOrderRecursionTraverse(T->lchild);
    PreOrderRecursionTraverse(T->rchild);
}
//--中序遍历递归算法--  
void InOrderRecursionTraverse(BiTree T)
{
    if (T == NULL)
        return;
    InOrderRecursionTraverse(T->lchild);
    printf("%c", T->data);
    InOrderRecursionTraverse(T->rchild);
}
//--后序遍历递归算法--  
void PostOrderRecursionTraverse(BiTree T)
{
    if (T == NULL)
        return;
    PostOrderRecursionTraverse(T->lchild);
    PostOrderRecursionTraverse(T->rchild);
    printf("%c", T->data);
}
//--先序遍历二叉树T的非递归算法--  
void PreOrderWithoutRecursion(BiTree T)
{
    if (T == NULL)  
        return;
    BiTNode* p = T;
    stack s;
    while (!s.empty() || p) 
    {
        if (p)
        {
            cout <1)<< p->data;
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            s.pop();
            p = p->rchild;
        }
    }
    cout <if (T == NULL)
        return;
    BiTNode * p = T;
    stack s;
    while (!s.empty() || p)
    {
        if (p)
        {
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            s.pop();
            cout << setw(1) << p->data;
            p = p->rchild;
        }
    }
}
//后序遍历  
void PostOrderWithoutRecursion(BiTree T)
{
    if (T == NULL)
        return;
    stack s;
    BiTNode* pCur, *pLastVisit; //pCur:当前访问节点,pLastVisit:上次访问节点  
    pCur = T;
    pLastVisit = NULL;
    //先把pCur移动到左子树最下边  
    while (pCur)
    {
        s.push(pCur);
        pCur = pCur->lchild;
    }
    while (!s.empty())
    {
        //走到这里,pCur都不是空,并已经遍历到左子树底端。
        pCur = s.top();//取出栈顶元素
        s.pop();
        //一个根节点被访问的前提是:无右子树或右子树已被访问过  
        if (pCur->rchild == NULL || pCur->rchild == pLastVisit)
        {
            cout << setw(1) << pCur->data;
            //修改最近被访问的节点  
            pLastVisit = pCur;
        }
        else
        {
            //根节点再次入栈  
            s.push(pCur);
            //进入右子树,且可肯定右子树一定不为空  
            pCur = pCur->rchild;
            while (pCur)
            {
                s.push(pCur);
                pCur = pCur->lchild;
            }
        }
    }
    cout << endl;
}
//---------------------------层次遍历-----------------------------
void init_queue(queue &q)             // 初始化队列函数
{
    q.front = 0;
    q.rear = 0;
}
int empty_queue(const queue &q)       // 判队空函数
{
    if (q.front == q.rear) 
        return 1;
    return 0;
}
int into_queue(queue &q, BiTNode *bp) // 入队函数
{
    if ((q.rear + 1) % maxlen == q.front) 
        return 0;
    q.rear = (q.rear + 1) % maxlen;
    q.data[q.rear] = bp;
    return 1;
}
BiTNode *out_queue(queue &q)           // 出队函数
{
    q.front = (q.front + 1) % maxlen;
    return q.data[q.front];
}
//--层次遍历二叉链表函数--
void traverse(BiTNode *bp)      
{
    BiTNode *p;
    queue Q;
    init_queue(Q);                   //初始化队列;
    if (bp != NULL) 
        into_queue(Q, bp);           //若bp非空则bp入队;
    while (!empty_queue(Q))          //当队列非空, 重复下列操作:
    {
        p = out_queue(Q);            //出队;
        cout<1)<data;      //访问出队指针所指结点的元素;
        if (p->lchild != NULL)
            into_queue(Q, p->lchild);//若该结点左指针非空则入队;
        if (p->rchild != NULL)
            into_queue(Q, p->rchild);//若该结点右指针非空则入队;
    }
    cout << endl;
}

/**************************主函数*****************************/
int main()
{
    //*** 按照先序顺序输入:   AB#D##C##
    BiTree T = NULL;
    printf("按先序遍历输入二叉,其中空结点为'#'):\n");
    T = CreateBiTree(T);
    //---------------递归遍历-------------
    printf("\n递归先序遍历:\n");
    PreOrderRecursionTraverse(T);
    printf("\n递归中序遍历:\n");
    InOrderRecursionTraverse(T);
    printf("\n递归后序遍历:\n");
    PostOrderRecursionTraverse(T);
    //---------------非递归遍历------------
    printf("\n非递归先序遍历:\n");
    PreOrderWithoutRecursion(T);
    printf("\n非递归中序遍历:\n");
    InOrderNonRecursionTraverse(T);
    printf("\n非递归后序遍历:\n");
    PostOrderWithoutRecursion(T);
    //---------------层次遍历-------------
    printf("\n层次遍历: \n");
    traverse(T);
    printf("\End.....\n");
    return 0;
}

你可能感兴趣的:(机器学习算法)