C++实现 链表存储二叉树

前言:国内很多教材,讲完二叉树的结构,就直接开始讲二叉树的遍历,我就觉得很奇怪,你连个完整的二叉树都没创建,遍历什么,于是我写了下面这篇文章,详细介绍了创建过程,然后再说遍历,循序渐进

1.什么是二叉树?什么是完美二叉树和完全二叉树?

直接上图
在这里插入图片描述
可以看到,图中的根结点拥有左右两个结点,同时左右两个结点,又是一棵独立的、互不相交的树分别称为左子树、右子树,这就是二叉树名字的由来

  • 完美二叉树:又称满二叉树,上图就是一棵完美二叉树,所有分支结点都存在左子树和右子树并且所有叶子(无子树的结点)都在同一层上。直观感觉整棵树都是满的
  • 完全二叉树:如果编号为i的结点与同样深度的满二叉树中编号i的结点位置一样,则这棵二叉树称为完全二叉树 ,其实就是满二叉树少了某个部分,如下
    在这里插入图片描述

由于当空结点很多时,二叉树的顺序存储结构会造成空间浪费,一般只适用于满二叉树,所以通常使用链表来存储二叉树,这种链表称二叉链表

2.二叉链表的结点结构定义

typedef int ElemntType;
struct Bintree_Node
{
ElementType data;//数据域
Bintree_Node* left;//左子树指针
Bintree_Node* right;//右子树指针
}

3.创建一个二叉链表

void Create(Bintree_Node** p)//形参为指针的指针,那么*p就是传入的指针
{
    ElementType temp;
    cout<<"请输入数据";
    cin>>temp;
    if(temp==0)//这里我们用'0'来指示创建一个空结点,对于不同的数据,这个标识可以任意设置
    {
      *p=Null;
    }
    else
   	{
      *p=new Bintree_Node;//如果不空,就创建一个节点
      (*p)->data=temp;//存入数据,注意要用(*p),因为->的优先级比*高
      Create(&(*p)->left);//递归创建左结点,实参是左指针的地址
      Create(&(*p)->right);
    }
}
void main()
{
	Bintree_Node* P = NULL;
	Create(&P);
}

假设创建一个3层,共7个结点的二叉树。根结点中存放数据为10,第二层两个结点都为5,第三层的三个结点分别存1、2、3、4,示意图如下
在这里插入图片描述
(圆圈中的为存储的数据,同时把结点从上到下,从左到右,依次编号)

从键盘输入如下
在这里插入图片描述
你一定会很好奇,为什么是这样的输入,才能创建这样一个二叉树

4.创建的具体过程分析

  • 首先输入10,判断不为空,然后创建一个根结点,把10存进根结点的data中,此时*p指向根结点(A)
  • 然后输入5,判断不为空,取根结点中的left指针的地址传给Create函数,运行Create(&(*p)->left),创建第二层的B结点,并把数据存入,此时*p指向的是B结点
  • 然后输入1,判断不为空,取B结点中的left指针的地址,继续递归运行Create(&(*p)->left),创建第三层的D结点,并把数据存入,此时*p指向的是D结点
  • 然后输入0,判断为空,即D结点的左子树为空
  • 然后输入0,判断为空,即D结点的右子树为空
  • 然后输入2,判断不为空,取B结点中的right指针的地址,继续递归运行Create(&(*p)->left),创建第三层的E结点,并把数据存入,此时*p指向的是E结点
  • 然后输入0,判断为空,即E结点的左子树为空
  • 然后输入0,判断为空,即E结点的右子树为空
    至此,左半边的树,就创建完成了,右边也是同理,总之整个创建顺序是ABDECFG

其实整个创建顺序,与后面要说的二叉树的三种遍历方式中的先序遍历是一样的,关于二叉树的遍历请看C++详解 二叉树的三种遍历方式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值