数据结构——二叉树

1 二叉树定义

  是n(n>0)个结点的有限集合,当n=0是称为空树;在任意一棵非空树中:有且仅有一个根结点,当n>1时,除根结点外的其余结点可分为左子树和右子树;

 

 

1.1 二叉树特点

   

1.2 二叉树形态

 

1.3 特殊二叉树

1.3.1 斜树

  左斜二叉树:二叉树的所有结点都只有左子树

  右斜二叉树:二叉树的所有结点都只有右子树

   

1.3.2 满二叉树

  一棵深度为k,且有2k-1个结点的二叉树

  特点:

    每一层上的结点树总是最大结点数;

    所有枝结点(枝结点就是下图中前7个结点)都有左右子树;

    可对满二叉树的结点进行连续编号,若规定从跟结点开始,按“自上而下,自左向右”的原则进行;

     

1.3.3 完全二叉树

  如果深度为k,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应

   

  注:对于上图的完全二叉树,叶子结点不能出现在第二层,只能出现在第三或第四层,因为在第二层不能满足与满二叉树的编号一一对应。

  特点:

    1.完全二叉树是满二叉树的一部分,而满二叉树是完全二叉树的特例

    2.若完全二叉树的深度为k,则所有的叶子结点都出现在第k层或k-1层

    3.对于任一结点,如果其右子树的最大层次为L,则其左子树的最大层次为L或L+1

2 二叉树的性质

  性质1:在非空二叉树中,第i层上至多有2i-1个结点(i>=1)

  性质2:深度为k的二叉树,至多有2k-1个结点(k>=1)

  性质3:对任何一棵二叉树,若其叶子结点为n0,度为2的结点数为n2,则n0=n2+1;

  性质4:具有n个结点的完全二叉树,其深度为log2n+1

  性质5:如果对一棵有n个结点的完全二叉树,其结点按层编号,对任意结点i有(n>=i>=1)

           如果i=1,则结点i是二叉树的根;

           如果i>1,择期双亲结点为i/2;

           如果2i>n,则结点i无左孩子,即为叶子结点,否则其左孩子结点为2i

           如果2i+1>n,则结点i无右孩子,否则其右孩子结点为2i+1

3 二叉树的存储结构

3.1 二叉树的顺序存储结构

3.1.1 满二叉树的顺序存储结构

 

3.1.2 完全二叉树的顺序存储结构

 

3.1.3 一般二叉树的顺序存储结构

 

3.2 二叉树的链式存储结构

 

3.2.1 二叉树链式结构定义

typedef int DataType
typedef struct BitNode
{
  DataType data;
  struct BitNode *left,*right;
}BitNode;

3.2.2 链式存储结构扩展

 

3.2.3 扩展链式存储结构定义

typedef int DataType
typedef struct BitNode
{
  DataType data;
  struct BitNode *left,*right,*parent;
}BitNode;

4 二叉树遍历

  遍历

    是按照指定的规律,从根结点开始,对二叉树的每个结点访问一次,且仅访问一次;

    访问是指对结点做某种处理,如:输出信息、修改结点的值等;

  遍历方式

    二叉树是一种非线性结构

      每个结点都可能有左右两棵子树

      需要寻找一种规律,使二叉树的结点能排列在一个线性列队上,从而便于遍历

    二叉树的基本组成

      根结点、左子树、右子树

      依次遍历这三部分就是遍历了二叉树

    若以L、D、R分别表示遍历左子树、遍历根结点、遍历右子树

      则有六种遍历方案:DLR、DRL、LDR、LRD、RDL、RLD

      若规定先左后右,则只有三种情况:DLR:先序遍历

                                      LDR:中序遍历

                                      LRD:后序遍历

4.1 先序遍历

  遍历根结点、遍历左子树、遍历右子树

  

void preOrderTraverse(BitNode *root)
{
  if(root==NULL)
    return;
  printf("%d",root->data);
  preOrderTraverse(root->left);
  preOrderTraverse(root->right);
}

4.2 中序遍历

  遍历左子树、遍历根结点、遍历右子树

   

void inOrderTraverse(BitNode *root)
{
  if(root==NULL)
    return;
  preOrderTraverse(root->left);
  printf("%d",root->data);
  preOrderTraverse(root->right);
}

4.3 后续遍历

  遍历左子树、遍历右子树、遍历根结点

   

void postOrderTraverse(BitNode *root)
{
  if(root==NULL)
    return;
  preOrderTraverse(root->left);
  preOrderTraverse(root->right);
  printf("%d",root->data);
}
posted @ 2019-01-07 09:44  dongry  阅读(407)  评论(0编辑  收藏  举报