0

0

二叉树(2)二叉树创建的3种方法,二叉树的递归遍历,二叉树的销毁

php中文网

php中文网

发布时间:2016-06-07 15:49:20

|

2348人浏览过

|

来源于php中文网

原创

1.二叉树创建的3种方法 在嵌套法创建二叉树的过程中,递归终止条件是十分重要设置的一环。节点数据是char类型的二叉树,嵌套创建时,很多人会用一个字符,比如输入流中的“ ”(空)来设置递归结束。倘若节点数据为int类型,则稍微复杂, 首先我们在输入时必须

1.二叉树创建的3种方法    

       在嵌套法创建二叉树的过程中,递归终止条件是十分重要设置的一环。节点数据是char类型的二叉树,嵌套创建时,很多人会用一个字符,比如输入流中的“ ”(空格)来设置递归结束。倘若节点数据为int类型,则稍微复杂,首先我们在输入时必须使用“空格,制表,换行”这3者之一间隔输入的数,且cin读取数据时候cin会跳过三种空格,因此有的人使用某个数比如“0, -1”设置递归终止,但是要求某个节点的数值就是递归终止判断条件所设置的值比如‘-1’呢,显然这不符合程序的完整性。基于此,本文提供了一种思路。

    这里,我们总结了3种二叉树创建方法。约定,二叉树节点定义如下:

typedef struct BinaryTreeNode  
{  
    int data;  
    BinaryTreeNode * leftchild;  
    BinaryTreeNode * rightchild;  
}Node,*NodePoint;

   意图构建成的二叉树如下图所示:

二叉树(2)二叉树创建的3种方法,二叉树的递归遍历,二叉树的销毁

第一种方法:不带参数的二叉树构建

Node *Create()//二叉树的创建,不带参数
{
    Node *root;
    if(cin.peek()=='#')
     {cin.get();return NULL;}
    else
     {root = new Node;
	  cin>>root->data;//前序创建。
	  root->leftchild= Create();
	  root->rightchild= Create();
      return root;
    }
}
   可以观察到,返回为节点指针类型。

第二种方法:带一个参数的二叉树创建

void Create(NodePoint* root)//带一个参数的二叉树创建,注意形参为指针的引用或者双重指针
{
    if(cin.peek()=='#')
     {cin.get();*root=NULL;}
    else
    {*root = new Node;
     cin>>(*root)->data;//前序创建
     Create(&(*root)->leftchild);
     Create(&(*root)->rightchild);
    }
}

       可以观察到,形参为指向节点指针的指针的指针,即双重指针。如上所示,递归和赋值写法稍显不同。

     总结方法一,方法二的递归终止条件。使用cin.peek()检查输入流下一个字符是否为“#”,cin.peek()只检查输入流并不抽取删掉。倘若是,结束递归,并使用cin.get()将“#”从输入流抽取并删掉。使用如下代码建立如上图所示的目标二叉树时:

NodePoint Root=NULL;
Root=Create();//不带参数构建
Create(&Root);//带一个参数构建,此处形参为双重指针
      输入为:“35 13 0##-15#19##-7##”。当然,两种方法均需要使用前序遍历创建。‘#’控制递归截止,“ ”代表间隔int数据。这两种方法只适合前序创建。

第三种方法:两个形参的二叉树创建函数

void  Create( NodePoint &root , int data )
{      
    Node *p = new Node;
    p->data=data;p->leftchild=0;p->rightchild=0;
    if(!root)
      root=p;
    else if( p->datadata )
      Create(root->leftchild,p->data );
    else
     Create(root->rightchild,p->data );       
}
    调用如下:
while(data<20)
{
    Create(Root,data);//此处形参为指针的引用,使用此种方法Root必须初始化
    data++;
}

      可以观察到。第一个形参为指针引用,输入参数和赋值参数与第二种方法的形参为双重指针不同。其次,二叉树满足”降顺序二叉数装入数据,满足左

2.二叉树的递归遍历

void PreTraverse(NodePoint Root)//嵌套前序遍历  
 {  
    if(Root) 
      {cout<data<<"  ";  
       PreTraverse(Root->leftchild);  
       PreTraverse(Root->rightchild);}  
 }  
void MidTraverse(NodePoint Root)//嵌套中序遍历  
 {  
       if(Root)  
       {MidTraverse(Root->leftchild);  
        cout<data<<"  ";  
        MidTraverse(Root->rightchild);}  
 }  
void PostTraverse(Node* Root)//嵌套后序遍历  
{  
    if (Root )  
    {PostTraverse(Root->leftchild);  
     PostTraverse(Root->rightchild);  
	 cout << Root->data<<"  ";}
}

3.二叉树销毁     

template
void destroy(TreeNode *& p)  //传递指针的引用,消毁函数,用来消毁二叉树中的各个结点
{
    if(p)
    {
        //错误 return之后 没有执行delete p
        //return destroy(p->Lchild);
        //return destroy(p->Rchild);
 
        destroy(p->Lchild);
        destroy(p->Rchild);
 
        //delete只能释放由用户通过new方式在堆中申请的内存,
        //是通过变量声明的方式由系统所声明的栈内存不能使用delete删除
 
        //delete和free函数一样,不修改它参数对应指针指向的内容,也不修改指针本身,
        //只是在堆内存管理结构中将指针指向的内容标记为可被重新分配
        delete p;
 
        //堆上内存释放 栈上指针并不销毁
        //此时p指向的地址未知,此时执行*p = ? 操作会导致不可预料的错误
        //但是可以重新赋值p = &x;
        //最好delete之后把P置空
        p = NULL;
 
    }
}
     容易混淆的错误声明:void destroy(TreeNode* p) 这种声明会创建一个局部的临时对象来保存传递的指针。虽然2个指针都执行同一块堆空间,delete局部指针 也会删除二叉树结构所占用的堆内存,但全局传递的那个指针将会是垃圾指针,会产生不可预料的错误。void destroy(TreeNode *& p) 此函数的参数为全局指针的一个别名,代表全局指针rootNode本身。这样p = NULL;能达到置空指针的目的。


Stable Diffusion 2.1 Demo
Stable Diffusion 2.1 Demo

最新体验版 Stable Diffusion 2.1

下载

本文有参考自:

C++ 二叉树的实现以及指针使用注意事项

二叉树常用算法总结

   



相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

42

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

4

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
550W粉丝大佬手把手从零学JavaScript
550W粉丝大佬手把手从零学JavaScript

共1课时 | 0.2万人学习

Swoft2.x速学之http api篇课程
Swoft2.x速学之http api篇课程

共16课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号