zoukankan      html  css  js  c++  java
  • 数据结构C语言实现----树

    树的基本知识点

      树的定义

      树的ADT(抽象数据类型)

      树的储存结构

      二叉树的定义

      二叉树的储存结构

      遍历二叉树

      二叉树的建立

    二叉树的ADT

      

    typedef struct BiTNode
    {
        ElemType date;        //结点的数据域
        struct BiTNode *lchild , *rchild;        //指向左孩子,右孩子
    } BiTNode ,  *BiTree;
    

      其中 BiTNode T  等价于  BiTNode *T

    二叉树的遍历

      有三种遍历方式:(V是访问visist  , L是左边left  ,R是右边right)(先访问根节点就叫先序,中间访问根节点就叫中序)

        VLR(先序):先访问根结点,再先序遍历左子树,再先序遍历右子树(后面有举例)

        LVR(中序):先中序遍历左子树,再访问根节点,再中序遍历右子树

        LRV(后序):先后序遍历左子树,再后序遍历右子树,再访问根节点

    遍历实例举例:

      每进去一个新节点都要操作三个步骤:V或L或R  

      (1)先序遍历

      

    void PreOrdeTraverse(BiTree T)
    {
        if (T)
        {//递归结束条件,T*为空
            visit(T->date);    //访问根节点
            PreOrdeTraverse(T->lchild);    //先序遍历左子树
            PreOrdeTraverse(T->rchild);    //先序遍历右子树
        }
    }
    

      

      (2)中序遍历

      中序遍历的方法与先序遍历一样,只不过顺序有改变,每当来到一个新节点,先看有没有左子树,有左子树,就进去左子树,没有就访问当前结点,之后再去找右子树,没有左右子树或左右子树结点都访问了,就回到上一个结点

      

    void InOrdeTraverse(BiTree T)
    {
        if (T)
        {
            InOrdeTraverse(T->lchild);
            visit(T->date);
            InOrdeTraverse(T->rchild);
        }
    }
    

      (3)后序遍历

      

    void PosOrdeTraverse(BiTree T)
    {
        if (T)
        {
            PosOrdeTraverse(T->lchild);
            PosOrdeTraverse(T->rchild);
            visit(T->date);
        }
    }
    

      

    二叉树的建立

      

    //先序序列创建一颗二叉树
    void CreatBiTree(BiTree *T)
    {
        char c;
        scanf("%c" , &c);
        if (c == '#')  *T = NULL;
        else
        {
            *T = (BiTNode*)malloc(sizeof(BiTNode));     //给结点申请一个空间
            (*T)->date = c;
            CreatBiTree(&((*T)->lchild));       //创建左子树
            CreatBiTree(&((*T)->rchild));       //创建右子树
        }
    }
    

      

      这里说明一下,为什么要传入树的指针的指针

      假如我们要用一个函数去改变一个整型变量 n 的值 ,我们知道必须传入这个变量n的指针进去这个函数,要不然函数中n的变化影响不了函数外的n值

      这里也是一样,我们要改变左右子树的地址,让他们指向一个新的空间,所以要传入左右子树地址的地址,才能在函数里改变他们的地址

      

    实例:

         以先序序列输入一棵树,并用三种遍历方式打印出这棵树,并且找到某个字母所在的层数

         我们下面这棵树为例(没有子树记作#)(找到大写字母D的所在层数)

         

    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct BiTNode
    {
        char date;         //结点的数据域
        struct BiTNode *lchild , *rchild;       //指向左孩子和右孩子
    }BiTNode , *BiTree ;
    //先序序列创建一颗二叉树
    void CreatBiTree(BiTree *T)
    {
        char c;
        scanf("%c" , &c);
        if (c == '#')  *T = NULL;
        else
        {
            *T = (BiTNode*)malloc(sizeof(BiTNode));     //给结点申请一个空间
            (*T)->date = c;
            CreatBiTree(&((*T)->lchild));       //创建左子树
            CreatBiTree(&((*T)->rchild));       //创建右子树
        }
    }
    //访问二叉树结点操作
    void visit(char c)
    {
        printf("%c",c);
    }
    //先序遍历二叉树
    void PreOrdeTraverse(BiTree T)
    {
        if (T)
        {
            visit(T->date);
            PreOrdeTraverse(T->lchild);
            PreOrdeTraverse(T->rchild);
        }
        
    }
    //中序遍历二叉树
    void InOrdeTraverse(BiTree T)
    {
        if (T)
        {
            InOrdeTraverse(T->lchild);
            visit(T->date);
            InOrdeTraverse(T->rchild);
        }
    }
    //后序遍历二叉树
    void PosOrdeTraverse(BiTree T)
    {
        if (T)
        {
            PosOrdeTraverse(T->lchild);
            PosOrdeTraverse(T->rchild);
            visit(T->date);
        }
    }
    //查找字母D在第几层
    void serch(BiTree T , int leavel)
    {
        if (T){
            if (T->date == 'D')
            {
                printf("D在第%d层!",leavel);
            }
            serch(T->lchild , leavel+1);
            serch(T->rchild , leavel+1);
        }
    }
    int main()
    {
        BiTree T;
        int leavel = 1;
        printf("请输入先序创建的二叉树,以#结束:");
        CreatBiTree(&T);
        printf("正在先序打印二叉树:");
        PreOrdeTraverse(T);
        putchar('
    ');
        printf("正在中序打印二叉树:");
        InOrdeTraverse(T);
        putchar('
    ');
        printf("正在后序打印二叉树:");
        PosOrdeTraverse(T);
        putchar('
    ');
        serch(T , leavel);
    }
    

      

    运行结果:

  • 相关阅读:
    第二阶段冲刺第三天
    第二阶段冲刺第二天
    第二阶段冲刺第一天
    软件工程概论第十四周学习进度
    软件工程概论第十三周学习进度
    软件工程概论第十二周学习进度
    搜狗输入法
    冲刺第十天
    第二阶段冲刺第七天
    第二阶段冲刺第六天
  • 原文地址:https://www.cnblogs.com/jerryleesir/p/13384498.html
Copyright © 2011-2022 走看看