zoukankan      html  css  js  c++  java
  • 二叉树

           上一篇,我们学习了二叉树的一些属性,定义,种类等。今天,我们主要学习它的存储结构、基本操作、与经典算法。二叉树之所以在数据结构中那么重要,正是因为它的存储结构、它的严谨规范。同时,也衍生了很多关于二叉树的经典算法,例如下面我们要学习的赫夫曼编码。不论,我们将来是做程序员、还是DBA。数据结构,是最最基本、最最重要的知识。我们把数据结构、计算机体系、计算机操作系统、网络安全等方面的知识掌握了,学习最新的编程语言、成熟框架等等,就如同砍瓜切菜般轻松。所以,我们一定要懂得磨刀不误砍柴功的道理。不要急于学习最新的编程语言,最新的框架,掌握基本知识才是王道。好了,闲话不多说了,开始吧。

    1.二叉链表:

         在学习树的存储结构时,我们知道单单使用顺序存储结构,不能很好的表现出树结点之间的逻辑关系。但是,二叉树有严格的规范,可以使用顺序存储结构。

    image

    上图是个完全二叉树,我们采用顺序存储的方式存储它。使用一维数组存放结点:

    image

    如果,不是一颗完全二叉树,我们可以把缺少的结点使用^表示出来,如下图:

    image

    浅色数字是不存在的结点,我们使用^表示。所以使用顺序存储是可以表示二叉树的结点之间逻辑。

    但是问题又来了,一颗深度为k的右斜树,结点有k个,但是需要开辟2^k-1个空间。这是一个极大的浪费,是不可取的。

    image

    所以,二叉链表就出场了。因为二叉树,最多只有两棵子树,所以我们可以这样设计结点结构:

    image

    data为数据域,lchild、rchild分别指向左子树的根结点、右子树的根结点。

    //二叉树的二叉链表结点结构定义
    typedef  struct  BiTNode  /*结点结构*/
    {
         TElemType  data;   /*结点数据*/
          BiTNode  *lchild、*rchild;/*左右孩子指针*/
    }BiTNode,*BiTree;

    image

    这是二叉树的二叉链表结点结构定义和结构示意图。

    2.遍历二叉树(Traversing Binary Tree):

       二叉树的遍历(traversing binary tree):从根结点开始,以某种次序遍历各个结点,确保每个结点都访问过并且仅访问过一次。 

       为什么要研究二叉树的遍历呢?我们通过图来展示二叉树的结构,非常直观易于理解。但是计算机,只有循环、判断等操作,计算机只能处理线性序列。二叉树的遍历,某种意义上就是将结点转变为线性序列。如果我们限制了从左向右遍历,那么有以下四种遍历方式:

    a.前序遍历:

    从根结点开始,先遍历左子树,在遍历右子树。

    image

    b.中序遍历:

    从根结点开始,先中序编列左子树,在遍历根结点,最后遍历右子树。note:从根结点开始,不是意味着先遍历根结点。

    image

    c.后序遍历:

    从左到右,先叶子结点,再根结点。

    image

    D.层次遍历:

    从根结点开始,从上而下,同一层中从左到右的顺序遍历。

    image

    下面我看一下各中遍历方法的实现代码:

    /*二叉树的前序遍历递归算法*/
    void PreOrderTraverse(BiTree T)
    {
              if(T==Null)  //如果是空树,则返回
                 return;
         printf("%C",T-data);//打印数据,可以换成任何操作      
        PreOrderTraverse(T->lchild); //前序访问左子树
        PreOrderTraverse(T->rchild);//前序访问右子树
             
    }
     
     
     /*二叉树的中序递归算法*/
    void InOrderTraverse(BiTree T)
    {
            if(T==Null)    //判断树是否为空
             return;
           InOrderTraverse(T->lchild);//中序遍历左子树
           Printf("%c",T->data);  //打印数据,可以换成任何操作
           InOrderTraverse(T->rchild);//中序遍历右子树
    }
    /*二叉树的后序递归算法*/
    void PostOrderTraverse(BiTree T)
    {
         if(T==Null) //判断树是否为空
            return ;
        PostOrderTraverse(T->lchild);//后序遍历左子树
       PostOrderTraverse(T->rchild);//后序遍历右子树
       Printf("%C",T->data);//打印数据,可以换成任何操作
    }

    以上就是二叉树不同遍历次序的实现算法,这些算法我们用到了递归。递归算法可以使我们的算法更加飘逸,简洁。

  • 相关阅读:
    HL7及PIX相关的测试工具
    HDU4570----Multi-bit Trie----简单的DP
    hdu2248
    poj 3693 Maximum repetition substring (后缀数组)
    高性能通道
    volyaire重振Infiniband
    利用iWARP/RDMA解决以太网高延迟
    linux 单网卡来绑定多IP实现多网段访问以及多网卡绑定单IP实现负载均衡
    C细节学习
    每2秒获取系统的赋值及内存使用率
  • 原文地址:https://www.cnblogs.com/VitoCorleone/p/4026883.html
Copyright © 2011-2022 走看看