二叉树、基本概念、特性、创建和遍历(C++)


二叉树


二叉树定义

树是由n( n ≥ 0 n\geq0 n0)个节点组成的有序集合,二叉树则是有两个节点的树结构,二叉树的每个结点至多只有二棵子树,通常称为“左子树”和“右子树”。如下图:

            1
          /   \
         2     3
        / \   / \
       4   5 6   7

二叉树的基本概念

  • 树的特点
    • 没有父节点的节点称为根节点
    • 每个非根节点只有一个父节点
    • 除了根节点外,每个节点可以分为多个不相交的节点
  • 树的基本术语
    • 节点的度:节点拥有子树的数目,如上树节点“2”拥有子节点“4”和“5”,所以它的度为‘2’,节点“4”没有子节点,所以其度为‘0’
    • 叶子节点:度为零的节点
    • 分支节点:度不为零的节点
    • 树的度:树中节点最大的度
    • 层次:根节点的层次为“1”,其余节点的层次为其父节点的层次加 1
    • 树的高度:树中节点的最大层次
  • 二叉树的性质
    • 二叉树的第 i i i层上节点的数目最大为 2 i − 1 , i ≥ 1 {2^{i-1},i\geq1} 2i1i1
    • 深度为 k k k的二叉树最大有 2 k − 1 {2^{k}-1} 2k1个节点, k ≥ 1 k\geq1 k1
    • 在任意一棵二叉树中,若终端结点的个数为 n 0 n_0 n0,度为2的结点数为 n 2 n_2 n2,则 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1
  • 二叉树的类型
    • 满二叉树:高度为 h h h,并且有 2 h − 1 {2^{h}-1} 2h1个节点的二叉树

                  1
               /     \
             2         3
           /   \     /   \
          4     5   6     7
              满二叉树
                  1
               /     \
             2        3
           /        /   \
          4        6     7
              非满二叉树
      
    • 完全二叉树:一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下一层的叶结点集中在靠左的若干位置上。这样的二叉树称为完全二叉树

      • 特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树

                  1
               /     \
             2         3
           /   \     /   \
          4     5   6     7
        满二叉树也是完全二叉树
                 1
               /     \
             2         3
           /   \     /   
          4     5   6    
              完全二叉树
                  1
               /     \
             2         3
           /   \         \
          4     5         7 
            不是完全二叉树
        
    • 二叉查找树

      • 定义:二叉查找树(Binary Search Tree),又被称为二叉搜索树。设 x x x为二叉查找树中的一个结点, x x x节点包含关键字 k e y key key,节点 x x x k e y key key值记为 k e y [ x ] key[x] key[x]。如果 y y y x x x的左子树中的一个结点,则 k e y [ y ] ≤ k e y [ x ] key[y] \leq key[x] key[y]key[x];如果y是x的右子树的一个结点,则 k e y [ y ] ≥ k e y [ x ] key[y] \geq key[x] key[y]key[x]

                      7
                    /   \ 
                  /       \
                 4         9
               /    \     / \
              2       6  8   10
            /   \    /
           1     3  5
        
      • 性质1: 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值,如节点1<2

      • 性质2:任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;如节点3>2

      • 性质3:任意节点的左右子树也是二叉查找树

      • 性质4:没有键值相等的节点

    • 其他二叉树:线索二叉树、平衡二叉树在此先不叙述

二叉树的存储结构

  • 顺序结构:用数组来存储,并且结点的存储位置,也就是数组的下标要能体现结点之间的逻辑关系。顺序存储结构一般只用于完全二叉树
  • 链式结构:用链表存储,每个节点包含指向左右两个节点的指针

二叉树的遍历

  • 二叉树如下:

                      7
                    /   \
                  /       \
                 4         9 
               /    \     / \
              2       6  8   10
            /   \    /
           1     3  5
    
  • 前序遍历:先访问根节点->左子树->右子树,则上二叉树前序遍历顺序为:7->4->2->1->3->6->5->9->8->10

  • 中序遍历:先访问左子树->根节点->右子树,则访问顺序为:1->2->3->4->5->6->7->8->9->10

  • 后序遍历:先访问左子树->右子树->根节点,则访问顺序为:1->3->2->5->6->4->8->10->9->7

代码

二叉树的创建

  • 例如要创建以下二叉树(非完全二叉树):输入‘#’表示节点为空

                    4
                  /    \
                 1     7
                /  \   /  \
               9    3 a    b 
              / \     /
             8   6   0
    

    则按照先序顺序输入为:

    4->1->9->8->#->#->6->#->#->3->#->#->7->a->0->#->#->#->b->#->#
    
    • 如果选择char型数据,可以直接输入:> 4198##6##3##7a0##b##
    //定义包含左右两个子节点指针的结构体
     typedef struct node
    {
        // int data;//存储int型数据
        char data;
        struct node *Lchild;
        struct node *Rchild;
    } BittreeNode;
    
  • 创建:利用递归,先指定一个根节点,然后在此先递归左子树,后递归右子树

//建立二叉树,从根节点x补全为二叉树,先序输入#(或者0)表示空节点,代表子树结尾(*&x:指针的引用,因为后面会修改x的地址)
void CreateBitree(BittreeNode *&x)
{
    char c;
    // int c;
    cin >> c;
    //如果输入字符为 # ,则令该节点指针为空
    if (c == '#')
    {
        x = nullptr;
    }
    // if (c == 0)
    // {
    //     x = nullptr;
    // }
    // 否则创建一个节点,并把x指向该节点
    else
    {
        x = new BittreeNode;
        x->data = c;
        CreateBitree(x->Lchild); //递归创建左子树
        CreateBitree(x->Rchild);
    }
}

前序输出

// 递归 先序遍历,先根后左再右
void preTraverse(BittreeNode *T)
{
    if (T)
    {
        cout << T->data << " ";
        preTraverse(T->Lchild);
        preTraverse(T->Rchild);
    }
}

主函数

    int main()
  {
      BittreeNode *X = new BittreeNode; //指针类型
      CreateBitree(X);
      cout << "二叉树创建完成!" << endl;
      cout << "前序遍历二叉树:" << endl;
      preTraverse(X);
      cin.get();
      return 0;
  }

中序遍历和后序遍历以及非递归方式后续再写

演示

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值