• 二叉树的创建


    对于创建一棵二叉树,首先想到的方法是使用递归思想进行。这里,采用先序递归创建二叉树。

    首先介绍下自己写的二叉树的定义:

    1 typedef int TElementType;
    2 
    3 typedef struct BiTNode
    4 {
    5     TElementType data;
    6     BiTNode* leftChild,*rightChild;
    7 } BiTNode,*BiTree;

    1.先序递归创建二叉树

    先附上自己最开始写的代码:

     1 //太丑了!!
     2 void CreateTreeDLR(BiTree _biTree)
     3 {
     4     TElementType data;
     5     cin>>data;
     6     if(data==0)
     7     {
     8        _biTree=NULL;
     9         return;
    10     }
    11     _biTree->data=data;
    12     _biTree->leftChild=new BiTNode();
    13     FillTreeDLR(_biTree->leftChild);
    14     _biTree->rightChild=new BiTNode();
    15     FillTreeDLR(_biTree->rightChild);
    16 }

    因为需要传入一个BiTree类型,所以需要在外部初始化一个BiTree类型。这时候问题就来了,但出现终止条件0时,虽然能正常结束递归,但_biTree=NULL语句对外层的BiTree对象根本不起作用。所以会导致出现一个不含值的BiTree类型。就会出现如下情况:

    input:1 2 4 0 0 5 0 0 3 6 0 0 7 0 0

    output:1 2 4 0 0 5 0 0 3 6 0 0 7 0 0 (使用先序遍历)

    输出结果出现0,完全不是我们想要的。

    既然知道了问题所在,那么进行如下改进:

     1 //传址的方法,也解决了因为传值需要在外部初始化BiTNode的问题
     2 //怎么一开始就转不过来!!
     3 void FillTreeDLR(BiTree &_biTree)
     4 {
     5     TElementType data;
     6     cin>>data;
     7     if(data==0)
     8     {
     9        _biTree=NULL;
    10     }
    11     else
    12     {
    13     _biTree=new BiTNode();
    14     _biTree->data=data;
    15     FillTreeDLR(_biTree->leftChild);
    16     FillTreeDLR(_biTree->rightChild);
    17     }
    18 }

    当然,如果不想使用传入参数,可以采用返回值得形式。

     1 //这个代码貌似还是有点违反“不能返回局部初始化的指针”这一原则
     2 BiTNode* CreateTreeDLR()
     3 {
     4     TElementType data;
     5     cin>>data;
     6     if(data==0)
     7     {
     8         return NULL;
     9     }
    10     BiTNode* root=new BiTNode();
    11     root->data=data;
    12     root->leftChild=CreateTreeDLR();
    13     root->rightChild=CreateTreeDLR();
    14     return root;
    15 }

    执行结果符合我们的需求:

    input:1 2 4 0 0 5 0 0 3 6 0 0 7 0 0

    output:1 2 4 5 3 6 7  (使用先序遍历)

    2.非递归创建二叉树

     非递归创建二叉树的思想跟层序遍历的思想类似,利用到队列,当弹出一个结点时,对当前结点进行赋值,如果值为空(这里值是0),则表明该结点无后续子结点;否则,将该结点的左右孩子入队列。依此过程,直到队列为空,结束。

    但是在一开始创建二叉树的时候,还是因为对指针的掌握不够,还是犯了将指针进行传值操作,后面使用指针的指针来解决这问题的。这一点在以后的学习中再怎么强调也不为过啊,指针真的把我绕晕了。

    首先,重新定义了下二叉树。

    1 typedef struct BiTNode
    2 {
    3     TElementType data;
    4     BiTNode* leftChild,*rightChild;
    5 } BiTNode,*BiTree,**BiTreePtr;/*新添加指针的指针*/

    下面是我实现的非递归创建二叉树的算法,说实话,对于下面指针的指针的用法,要如何改进优化,我晕乎着,反正是看不出来了。

     1 void CreateTreeNonRecur(BiTree& root)
     2 {
     3     queue<BiTreePtr> q;
     4     TElementType data;
     5     q.push(&root);
     6     while(q.size()!=0)
     7     {
     8         //弹出要配置的结点
     9         BiTreePtr r=q.front();
    10         q.pop();
    11         //输入数据
    12         cin>>data;
    13         if(data==0){
    14             *r=NULL;
    15             continue;
    16         }
    17         *r=new BiTNode();
    18         (*r)->data=data;
    19         //压入新的子结点
    20         q.push(&((*r)->leftChild));
    21         q.push(&((*r)->rightChild));
    22     }
    23 }

    测试结果:

    input:1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0

    output:1 2 4 8 5 3 6 7 (使用先序遍历)

  • 相关阅读:
    python时间类型相关
    python调用函数
    LightGBM
    保存训练好的模型并调用
    Bootstrap Table
    Jquery 获取元素上绑定的事件
    C# DLL 反编译改代码
    FastReport C# 导出
    Log4Net
    BootStrap Table
  • 原文地址:https://www.cnblogs.com/lsr-flying/p/4504649.html
Copyright © 2020-2023  润新知