二叉树的遍历的应用

创建如下图所示的二叉树:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MAXSIZE 100
typedef char ElemType;
typedef struct Node
{
    ElemType data;
    struct Node *lchild;
    struct Node *rchild;
}*BitTree,BitNode;
/*二叉树的基本操作*/
void InitBitTree(BitTree *T);//二叉树的初始化操作
void DestroyBitTree(BitTree *T);//销毁二叉树
void CreateBitTree(BitTree *T);//递归创建二叉树
void CreateBitTree2(BitTree *T,char str[]);//非递归创建二叉树
int InsertLeftChild(BitTree p,BitTree c);//二叉树的左插入操作
//如果二叉树c存在且非空,则将c插入到p所指向的左子树,使p所指结点的左子树成为c的右子树
int InsertRightChild(BitTree p,BitTree c);//二叉树的右插入操作
//如果二叉树c存在且非空,则将c插入到p所指向的右子树,使p所指结点的右子树成为c的右子树
BitTree Point(BitTree T,ElemType e);//返回二叉树结点的指针操作
ElemType LeftChild(BitTree T,ElemType e);//返回二叉树的结点的左孩子元素值操作
ElemType RightChild(BitTree T,ElemType e);//返回二叉树的结点的右孩子元素值操作
int DeleteLeftChild(BitTree p);//二叉树的左删除操作
int DeleteRightChild(BitTree p);//二叉树的右删除操作
void PreOrderTraverse(BitTree T);//先序遍历二叉树的递归实现
void InOrderTraverse(BitTree T);//中序遍历二叉树的递归实现
void PostOrderTraverse(BitTree T);//后序遍历二叉树的递归实现
void PostOrderTraverse2(BitTree T);//后序遍历二叉树的非递归实现
void PreOrderTraverse2(BitTree T);//先序遍历二叉树的非递归实现
void InOrderTraverse2(BitTree T);//中序遍历二叉树的非递归实现  

#include "LinkBiTree.h"
void InitBitTree(BitTree *T)//二叉树的初始化操作
{
    *T = NULL;
}
void DestroyBitTree(BitTree *T)//销毁二叉树
{
    if(*T)
    {
        if((*T)->lchild)
        {
            DestroyBitTree(&((*T)->lchild));
        }
        if((*T)->rchild)
        {
            DestroyBitTree(&((*T)->rchild));
        }
        free(*T);
        *T = NULL;
    }
}
void CreateBitTree(BitTree *T)//递归创建二叉树
{
    ElemType ch;
    scanf("%c",&ch);
    if(ch == '#')
    {
        *T = NULL;
    }
    else
    {
        *T = (BitTree)malloc(sizeof(BitNode));
        if(!(*T))
        {
            exit(-1);
        }
        else
        {
            (*T)->data = ch;
            CreateBitTree(&((*T)->lchild));
            CreateBitTree(&((*T)->rchild));
        }
    }
}
void CreateBitTree2(BitTree *T,char str[])//递归创建二叉树
{
    char ch;
    BitTree stack[MAXSIZE];
    int top = -1;
    int flag,k;
    BitNode *p;
    *T = NULL,k = 0;
    ch = str[k];
    while(ch != '\0')
    {
        switch(ch)
        {
        case '(':
                stack[++top] = p;
                flag = 1;
                break;
        case ')':
            top--;
            break;
        case ',':
            flag = 2;
            break;
        default:
            p = (BitTree)malloc(sizeof(BitNode));
            p->data = ch;
            p->lchild = NULL;
            p->rchild = NULL;
            if(*T == NULL)
            {
                *T = p;
            }
            else
            {
                switch(flag)
                {
                case 1:
                    stack[top]->lchild = p;
                    break;
                case 2:
                    stack[top]->rchild = p;
                    break;
                }
            }
        }
        ch = str[++k];
    }
}
int InsertLeftChild(BitTree p,BitTree c)//二叉树的左插入操作
{
    if(p)
    {
        c->rchild = p->lchild;
        p->lchild = c;
        return 1;
    }
    return 0;
}
int InsertRightChild(BitTree p,BitTree c)//二叉树的右插入操作
{
    if(p)
    {
        c->rchild = p->rchild ;
        p->rchild = c;
        return 1;
    }
    return 0;
}
BitTree Point(BitTree T,ElemType e)//返回二叉树结点的指针操作
{
    BitTree Q[MAXSIZE];
    int front = 0,rear = 0;
    BitNode *p;
    if(T)
    {
        Q[rear] = T;
        rear++;
        while(front != rear)
        {
            p = Q[front];
            front++;
            if(p->data == e)
            {
                return p;
            }
            if(p->lchild)
            {
                Q[rear] = p->lchild ;
                rear++;
            }
            if(p->rchild)
            {
                Q[rear] = p->rchild ;
                rear++;
            }
        }
    }
    return NULL;
}
ElemType LeftChild(BitTree T,ElemType e)//返回二叉树的结点的左孩子元素值操作
{
    BitTree p;
    if(T)
    {
        p = Point(T,e);
        if(p && p->lchild)
        {
            return p->lchild->data;
        }
    }
    exit(-1);
}
ElemType RightChild(BitTree T,ElemType e)//返回二叉树的结点的右孩子元素值操作
{
    BitTree p;
    if(T)
    {
        p = Point(T,e);
        if(p && p->rchild)
        {
            return p->rchild->data;
        }
    }
    exit(-1);
}
int DeleteLeftChild(BitTree p)//二叉树的左删除操作
{
    if(p)
    {
        DestroyBitTree(&(p->lchild));
        return 1;
    }
    return 0;
}
int DeleteRightChild(BitTree p)//二叉树的右删除操作
{
    if(p)
    {
        DestroyBitTree(&(p->rchild));
        return 1;
    }
    return 0;
}
void PreOrderTraverse(BitTree T)//先序遍历二叉树的递归实现
{
    if(T)
    {
        printf("%2c",T->data);
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}
void InOrderTraverse(BitTree T)//中序遍历二叉树的递归实现
{
    if(T)
    {
        InOrderTraverse(T->lchild);
        printf("%2c",T->data);
        InOrderTraverse(T->rchild);
    }
}
void PostOrderTraverse(BitTree T)//后序遍历二叉树的递归实现
{
    if(T)
    {
        PostOrderTraverse(T->lchild);
        PostOrderTraverse(T->rchild);
        printf("%2c",T->data);
    }
}
void PreOrderTraverse2(BitTree T)//后序遍历二叉树的非递归实现
{
    BitTree stack[MAXSIZE];//定义一个栈,用于存放结点指针
    int top;//定义栈顶指针
    BitNode *p;//定义一个结点指针
    top = 0;//初始化栈
    p = T;
    while(p != NULL || top > 0)
    {
        while(p != NULL)//如果栈不空访问根结点,遍历左子树
        {
            printf("%2c",p->data);//访问根结点
            stack[top++] = p;//将p入栈
            p = p->lchild ;//遍历左子树
        }
        if(top > 0)//如果栈不空
        {
            p = stack[--top];//栈顶元素出栈
            p = p->rchild ;//遍历右子树
        }
    }
}
void InOrderTraverse2(BitTree T)//先序遍历二叉树的非递归实现
{
    BitTree stack[MAXSIZE];//定义一个栈,用于存放结点指针
    int top;//定义栈顶指针
    BitNode *p;//定义结点指针
    top = 0;//初始化栈
    p = T;
    while(p != NULL || top > 0)
    {
        while(p != NULL)//如果栈不空访问根结点,遍历左子树
        {
            stack[top++] = p;//将p入栈
            p = p->lchild ;//遍历左子树
        }
        if(top > 0)//如果栈不空
        {
            p = stack[--top];//栈顶元素出栈
            printf("%2c",p->data);//访问根结点
            p = p->rchild ;//遍历右子树
        }
    }
}
void PostOrderTraverse2(BitTree T)//中序遍历二叉树的非递归实现
{
    BitTree stack[MAXSIZE];//定义一个栈,用于存放结点指针
    int top;//定义栈顶指针
    BitNode *p,*q;//定义一个结点指针
    top = 0;//初始化栈
    p = T;
    q = NULL;
    while(p != NULL || top > 0)
    {
        while(p != NULL)//如果栈不空访问根结点,遍历左子树
        {
            stack[top++] = p;//将p入栈
            p = p->lchild ;//遍历左子树
        }
        if(top > 0)//如果栈不空
        {
            p = stack[top-1];//栈顶元素出栈
            if(p->rchild == NULL || p->rchild == q)
            {
                printf("%2c",p->data);//访问根结点
                q = p;
                p = NULL;
                top--;
            }
            else
            {
                p = p->rchild ;//遍历右子树
            }
        }
    }
}  

#include "LinkBiTree.h"  

int main(void)
{
    BitTree T,root;
    InitBitTree(&T);
    printf("根据输入二叉树的先序序列创建二叉树(‘#’表示结束):\n");
    CreateBitTree(&T);
    printf("二叉树的先序序列:\n");
    printf("递归:");
    PreOrderTraverse(T);
    printf("\n");
    printf("非递归:");
    PreOrderTraverse2(T);
    printf("\n");
    printf("二叉树的中序序列:\n");
    printf("递归:");
    InOrderTraverse(T);
    printf("\n");
    printf("非递归:");
    InOrderTraverse2(T);
    printf("\n");
    printf("二叉树的后序序列:\n");
    printf("递归:");
    PostOrderTraverse(T);
    printf("\n");
    printf("非递归:");
    PostOrderTraverse2(T);
    printf("\n");
    printf("根据括号嵌套的字符串建立二叉树:\n");
    CreateBitTree2(&root,"(a(b(c,d),e(f,(,g),h(i))))");
    printf("二叉树的先序序列:\n");
    PreOrderTraverse(root);
    printf("\n");
    printf("二叉树的中序序列:\n");
    InOrderTraverse(root);
    printf("\n");
    printf("二叉树的后序序列:\n");
    PostOrderTraverse(root);
    printf("\n");
    DestroyBitTree(&T);
    DestroyBitTree(&root);
    return 0;
}

运行结果如图:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-01 10:59:36

二叉树的遍历的应用的相关文章

【树4】二叉树的遍历

简介 遍历二叉树就是按照某种顺序,将树中的结点都枚举一遍,且每个结点仅仅访问一次.因为树不是线性的结构,遍历不像线性表那样简单,因此他的遍历需要特点的算法来完成. 从某种角度讲,对二叉树的遍历就是将树形结构转换为线性结构的操作. 二叉树的遍历方法主要有如下几种: 先序遍历:先访问root结点,再先序遍历左子树,再先序遍历右子树. 中序遍历:先中序遍历左子树,再访问root结点,再中序遍历右子树. 后序遍历:先后序遍历左子树,再后序遍历右子树,再访问root结点. 层遍历:从上到下,从左到右,一层

树、二叉树、遍历二叉树的总结

首先介绍树: 如上图所示就是一棵树,先介绍树的几个关键名词: 节点:A.B.C.D等都叫节点 节点的度:节点有几个分支,就叫节点的度,比如节点B有2个分支,那B的度为2 终端节点(叶子):没有分支的节点,如E.F.G.H 非终端节点:有分支的节点,如A.B.D.C 节点的层次:自上而下排列层次,A为1层,B为2层,D为3层 树的度:哪个节点的度最大,这个最大的度就是树的度,如图树的度为2 树的深度:简而言之,就是树有几层,如图的树的深度为4 我们接触最多的树是二叉树 二叉树:在计算机科学中,二叉

java生成二叉树和遍历

在java中实现二叉树和链表的方法都是在类中定义该类的对象引用 比如 class Tree { int data; Tree left; Tree right; } 这样的话当我们new一个Tree对象的时候,该对象就拥有了left和right两个对象,这样就起到了连接的 作用,在链表中就是连接了下一个,在树中就相当于边,这样就起到一个接一个的效果.总之,就是吧对象连接起来了. 下面是完整代码 package code; public class TwoTree { public static

【LeetCode-面试算法经典-Java实现】【107-Binary Tree Level Order Traversal II(二叉树层序遍历II)】

[107-Binary Tree Level Order Traversal II(二叉树层序遍历II)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). For example

4-9 二叉树的遍历 (25分)

4-9 二叉树的遍历   (25分) 输出样例(对于图中给出的树): Inorder: D B E F A G H C I Preorder: A B D F E C G H I Postorder: D E F B H G I C A Levelorder: A B C D F G I E H 代码:(都是遍历的算法) 1 // 4-9 二叉树的遍历 2 // 3 // Created by Haoyu Guo on 04/02/2017. 4 // Copyright ? 2017 Haoy

Java数据结构-二叉树及其遍历

二叉树的定义:n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互相不相交的.分别称为根结点的左子树和右子树的二叉树组成. 二叉树的特点: 0<=度<=2: 左右子树是有顺序的,不能颠倒: 不论有几棵子树,也要区分它是左子树还是右子树. 二叉树的五种基本形态: 空二叉树: 只有一个根结点: 根结点只有左子树: 根结点只有右子树: 根结点既有左子树又有右子树. 举例3个结点的二叉树的形态有: 下面说一些特殊的二叉树. 斜树:所有的结点都只有左子树的二叉

【转】算法之二叉树各种遍历

http://blog.csdn.net/sjf0115/article/details/8645991 树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用. 二叉树是每个结点最多有两个子树的有序树.通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree).二叉树常被用作二叉查找树和二叉堆或是二叉排序树.二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒.二叉树的第i层至多有2的 i -1次方个结点:

编程之美问题之二叉树层序遍历多种解法

二叉树的层序遍历(要求区分层,例如每层遍历完输出换行) 单单层序遍历非常简单,一个队列就搞定了,但是区分层则要麻烦些.总的思路无非就是在每次print的时候,要能通过某个东西 区分出当前节点是否是一层最后一个节点,或者下一层的最后一个节点,感觉有点类似于机器学习中找个区分度明显的特征: 1.自己的解法,在单队列基础上,输入队列的数据添加一个标志 ,LevelHeaded,同时,在后面插入两个孩子的时候,判断是否这次输出的是队头,如果是的话,先插 个队头标志,再插入孩子,而且插入一次之后,后面不能

数据结构第三部分:树与树的表示、二叉树及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树、集合及其运算

参考:浙大数据结构(陈越.何钦铭)课件 1.树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基本操作之一:查找(根据某个给定关键字K,从集合R 中找出关键字与K 相同的记录).一个自然的问题就是,如何实现有效率的查找? 静态查找:集合中记录是固定的,没有插入和删除操作,只有查找 动态查找:集合中记录是动态变化的,除查找,还可能发生插入和删除 静态查找——方法一:顺序查找(时间复杂度O(n)) int

数据结构——二叉树的遍历

"树"是一种重要的数据结构,本文浅谈二叉树的遍历问题,採用C语言描写叙述. 一.二叉树基础 1)定义:有且仅有一个根结点,除根节点外,每一个结点仅仅有一个父结点,最多含有两个子节点,子节点有左右之分. 2)存储结构 二叉树的存储结构能够採用顺序存储,也能够採用链式存储,当中链式存储更加灵活. 在链式存储结构中,与线性链表类似,二叉树的每一个结点採用结构体表示,结构体包括三个域:数据域.左指针.右指针. 二叉树在C语言中的定义例如以下: struct BiTreeNode{ int c;