二叉树的实现(二叉链表实现遍历操作)

  • 一、二叉树的遍历
  • 二、二叉链表的数据结构定义
  • 三、二叉链表类实现
    • 1.类声明
    • 2.BiTree->构造函数:Create创建二叉链表
    • 3.~BiTree->析构函数:Release释放二叉链表
    • 4.PreOrder->前序遍历
    • 5.InOrder->中序遍历
    • 6.PostOrder->后序遍历
    • 7.LevelOrder->层序遍历
  • 四、二叉链表的测试
    • 1.主函数
    • 2.输出结果
  • 五、源代码获取(免积分)
  • 六、二叉链表的应用

一、二叉树的遍历

  二叉树是一种重要的树状结构,因其结构相对简单,因此具有更广泛的应用。遍历时二叉树最基本的操作。二叉树的遍历指的是从根节点出发,将所有的节点访问一次并且仅访问一次。一颗二叉树分为根、左子树、右子树三个部分。根据访问的次序的不同可以将二叉树的遍历分为前序遍历、中序遍历、后序遍历和层次遍历。
  二叉树一般采用二叉链表存储。对于二叉树的每一个结点,都分配一个二叉链表结点,结点包括数据域data、左指针域lchild、右指针域rchild,data用来保存结点的数据信息,lchild域指向结点的左孩子,rchild指向结点的右孩子。结点结构如下图所示:

  二叉树的二叉链表存储结构如下所示:

二、二叉链表的数据结构定义

  二叉链表的数据结构可使用C++中的结构体定义,另外,由于二叉链表中的元素类型并不确定,因此可以使用模板机制。

/*位于BiTree.h文件中*/
template <class ElemType>
struct BiNode{ElemType data;BiNode<ElemType> *lchild,*rchild;
};

三、二叉链表类实现

1.类声明

/*位于BiTree.h文件中*/
template <class ElemType>
class BiTree{public:BiTree() {root=Create(root);}//构造函数,建立一颗二叉树~BiTree() {Release(root);}//析构函数,释放各个节点void PreOrder() {PreOrder(root);}//前序遍历二叉树void InOrder() {InOrder(root);}//中序遍历二叉树void PostOrder() {PostOrder(root);}//后序遍历二叉树void LevelOrder() {LevelOrder(root);}//层序遍历二叉树 private:BiNode<ElemType>* root;BiNode<ElemType>* Create(BiNode<ElemType>* bt) ;void Release(BiNode<ElemType>* bt);void PreOrder(BiNode<ElemType>* bt);void InOrder(BiNode<ElemType>* bt);void PostOrder(BiNode<ElemType>* bt);void LevelOrder(BiNode<ElemType>* bt);
};

2.BiTree->构造函数:Create创建二叉链表

  要对二叉树进行遍历,必须首先在内存中创建一颗由二叉链表存储的二叉树。二叉树的一个车遍历序列不能唯一地确定二叉树,例如前序遍历序列、中序遍历序列或者后续遍历序列。由二叉树得到扩展的二叉树,再由扩展的二叉树的前序遍历序列则可以唯一地确定二叉树。
  所谓扩展的二叉树指的是在原二叉树的末端添加虚结点,使原二叉树的所有结点的度都变为2。扩展的结点的数据可使用不会出现在正常结点的表示,例如‘#’。以下面这个二叉树为例;
  原二叉树:

  扩展二叉树:

  上图中的扩展二叉树的前序序列为:A B # # C D # # # 。
  BiTree()方法在类的声明中已经定义,其内部包含Create()方法,用来创建二叉链表,下面是Create()方法的实现。

/*位于BiTree.cpp文件中*/
template <class ElemType>
BiNode<ElemType>* BiTree<ElemType>::Create(BiNode<ElemType>* bt)
{char ch;cout<<"请输入创建一颗二叉树的结点数:"<<endl;cin>>ch;/* # 代表空二叉树 */ if(ch=='#')return NULL;else{bt=new BiNode<ElemType>;bt->data=ch;bt->lchild=Create(bt->lchild) ;//递归创建左子树bt->rchild=Create(bt->rchild) ;//递归创建右子树}return bt;
}

3.~BiTree->析构函数:Release释放二叉链表

  可利用二叉树的后序遍历释放二叉链表的各结点。算法描述如下:

/*位于BiTree.cpp文件中*/
template <class ElemType>
void BiTree<ElemType>::Release(BiNode<ElemType>* bt)
{/*按照后续遍历顺序释放二叉树*/if(bt!=NULL) {Release(bt->lchild);Release(bt->rchild);delete bt;//删除根节点 }
}

4.PreOrder->前序遍历

  前序遍历二叉树的操作定义为:若二叉树为空,则空操作返回;否则;
(1)访问根节点;
(2)前序访问根节点的左子树;
(3)前序访问根节点的右子树;
例如下面这个二叉树的前序遍历结果是:A B D G E C F

/*位于BiTree.cpp文件中*/
/*前序遍历*/
template <class ElemType>
void BiTree<ElemType>::PreOrder(BiNode<ElemType>* bt)
{if(bt==NULL)return ;else{cout<<bt->data<<" ";//访问根节点 PreOrder(bt->lchild);//遍历左子树 PreOrder(bt->rchild);//遍历右子树 }
}

5.InOrder->中序遍历

  中序遍历二叉树的操作定义为:若二叉树为空,则空操作返回;否则;
(1)中序访问根节点的左子树;
(2)访问根节点;
(3)中序访问根节点的右子树;
例如下面这个二叉树的中序遍历结果是:D G B E A C F

/*位于BiTree.cpp文件中*/
/*中序遍历*/
template <class ElemType>
void BiTree<ElemType>::InOrder(BiNode<ElemType>* bt)
{if(bt==NULL)return ;else{InOrder(bt->lchild);//遍历左子树 cout<<bt->data<<" ";//访问根节点 InOrder(bt->rchild);//遍历右子树 }
}

6.PostOrder->后序遍历

  后序遍历二叉树的操作定义为:若二叉树为空,则空操作返回;否则;
(1)后序访问根节点的左子树;
(2)后序访问根节点的右子树;
(3)访问根节点;
例如下面这个二叉树的后序遍历结果是:G D E B F C A

/*位于BiTree.cpp文件中*/
/*后序遍历*/
template <class ElemType>
void BiTree<ElemType>::PostOrder(BiNode<ElemType>* bt)
{if(bt==NULL)return ;else{PostOrder(bt->lchild);//遍历左子树 PostOrder(bt->rchild);//遍历右子树 cout<<bt->data<<" ";//访问根节点 }
}

7.LevelOrder->层序遍历

  层次遍历是从根节点开始,按照从上到下、从左到右的顺序遍历二叉树的结点,或者按照结点的层序编号遍历。下面这个二叉树的层序遍历结果是:A B C D E F G

  对二叉树进行层序遍历时,需要用队列来保存结点指针,以便于寻找其左右孩子结点。使用伪代码描述二叉树的层序遍历算法如下:

1.顺序队列Q初始化;
2.如果二叉树不为空,则将根指针入队;
3.当顺序队列Q不为空时循环:3.1 q=队头元素出队3.2 访问q的数据域3.3 若q存在左孩子,则将其左指针入队;3.4 若q存在右孩子,则将其右指针入队;

  层序遍历的代码如下:

/*位于BiTree.cpp文件中*/
/*层序遍历*/
template <class ElemType>
void BiTree<ElemType>::LevelOrder(BiNode<ElemType>* bt)
{const int MaxSize=100;/*采用顺序队列,假设不会发生溢出*/int front=-1,rear=-1;BiNode<ElemType>* Q[MaxSize] ,*q;if(bt==NULL)return;else{Q[rear++]=bt;//bt入队/*队列非空时进行循环*/ while(front!=rear){q=Q[front++];//队头出队 cout<<q->data<<" " ;//访问队头if(q->lchild!=NULL) //如果队友有左孩子,则左孩子入队Q[rear++] =q->lchild;if(q->rchild!=NULL) //如果队友有右孩子,则右孩子入队Q[rear++] =q->rchild;}}
}

四、二叉链表的测试

1.主函数

#include <iostream>
#include "BiTree.cpp"using namespace std;int  main() {BiTree<char> T;cout<<"------前序遍历------ "<<endl;T.PreOrder();cout<<endl;cout<<"------中序遍历------ "<<endl;T.InOrder( );cout<<endl;cout<<"------后序遍历------ "<<endl;T.PostOrder( );cout<<endl;cout<<"------层序遍历------ "<<endl;T.LevelOrder();cout<<endl;return 1;
}

2.输出结果

  按照下面这个扩展二叉树的顺序,依次输入:A B # # C D # # #。

输出结果如下:

请输入创建一颗二叉树的结点数:
A
请输入创建一颗二叉树的结点数:
B
请输入创建一颗二叉树的结点数:
#
请输入创建一颗二叉树的结点数:
#
请输入创建一颗二叉树的结点数:
C
请输入创建一颗二叉树的结点数:
D
请输入创建一颗二叉树的结点数:
#
请输入创建一颗二叉树的结点数:
#
请输入创建一颗二叉树的结点数:
#
------前序遍历------
A B C D
------中序遍历------
B A D C
------后序遍历------
B D C A
------层序遍历------
A B C D

五、源代码获取(免积分)

源代码地址

六、二叉链表的应用

1.二叉链表的遍历应用
2.求二叉树的最小深度
3.判断二叉树是否结构对称
4.判断二叉树是否关于中轴线对称
5.求二叉树的镜像

数据结构C++边学边做--二叉树的实现(二叉链表实现遍历操作)相关推荐

  1. 数据结构源码笔记(C语言):二叉平衡树的相关操作算法

    //二叉平衡树的相关运算 #include<stdio.h> #include<malloc.h> #include<string.h>typedef char I ...

  2. 计算二叉树宽度(二叉链表)

    通过层次遍历计算二叉树的宽度: int Broad(BiTree T) {if (T){BiTree p=NULL;queue<BiTree> Q;Q.push(T);int max = ...

  3. 数据结构-二叉链表的结构与实现

    目录 一.引言 二.什么是二叉链表 三.二叉链表的结构 四.二叉链表的实现 1. 创建二叉链表 2. 遍历二叉链表 3. 插入节点 4. 删除节点 五.应用场景 六.总结 七.代码示例 一.引言 数据 ...

  4. C语言递归实现二叉树(二叉链表)的三种遍历和销毁操作(实验)

    今天写的是二叉树操作的实验,这个实验有三个部分: ①建立二叉树,采用二叉链表结构 ②先序.中序.后续遍历二叉树,输出节点值 ③销毁二叉树 二叉树的节点结构定义 typedef struct BiTNo ...

  5. 理论基础 —— 二叉树 —— 二叉链表

    [二叉链表] 二叉树一般采用二叉链表存储,其基本思想是:令二叉树的每个结点对应一个链表结点,链表结点除了存放与二叉树结点有关的数据信息外,还要设置指示左右孩子的指针. template<clas ...

  6. 6-2-二叉树(二叉链表存储)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版...

    课本源码部分 第6章  树和二叉树 - 二叉树(二叉链表存储) --<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴 ...

  7. c++数据结构二叉树(二叉链表实现)基本操作实现

    二叉树: 二叉树(Binary tree)是树形结构的一个重要类型.许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二 ...

  8. 数据结构-二叉链表存储的二叉树(利用先序遍历)

    树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用.对于每一个结点至多只有两课子树的一类树,称其为二叉树.二叉树的链式存储结构是一类重要的数据结构,其形式定义如下: 而二叉树的前序.中序遍历 ...

  9. 数据结构:(翻转二叉树) 若二叉树采用二叉链表作存储结构,要交换其所有分支结点的左右子树的位置,采用()遍历方法最合适

    题目 若二叉树采用二叉链表作存储结构,要交换其所有分支结点的左右子树的位置,采用()遍历方法最合适?(北京航空航天大学1999,北京工业大学2016) A. 前序 B. 中序 C. 后序 D. 层次 ...

最新文章

  1. Missing number
  2. ASP.NET Core 添加统一模型验证处理机制
  3. 推荐使用:Vue.js ReactJS Angular 2 AngularJS
  4. html5学习新的知识总结(一)
  5. 在线代码片段管理工具gistbox + github
  6. 安卓逆向系列教程(二)APK 和 DEX
  7. firewalld的配置和使用
  8. 阿里云 Debian 9.2 安装 Java Web 环境
  9. c语言linux系统宏,Linux下C语言中的预定义宏
  10. 【读书笔记】浪潮之巅——公司史篇
  11. linux系统下UTF-8转GBK编码,使用汉字字库在LCD显示汉字
  12. PDFcrack暴力破解pdf密码
  13. pg比mysql优势_postgresql比mysql有多少优势
  14. 纯html+css制作banner轮播图
  15. 干货 | 京东云域名注册及备案最佳实践
  16. Mac设置重置Python3环境
  17. np.meshgrid()函数
  18. Android控件 SeekBar
  19. Gitstack CVE-2018-5955命令执行漏洞分析
  20. mysql8时区设置_解决MySQL8.0时区的问题步骤

热门文章

  1. 互联网思维(二)——流量时代,私域为王
  2. 光模块传输距离如何计算?
  3. 国网智能电表DLT645/DLT698.45协议规约驱动解析说明及命令示例
  4. linkage pathways
  5. 三菱FX5U多冲一切追剪程序
  6. 我的电磁学讲义14:动生电动势和感生电动势
  7. 手机——小灵通互发短信PDU编码注意事项
  8. 多层地层中的井筒及地层温度解析
  9. 红米K40s如何启用录屏功能
  10. 【计算机组成原理-chapter3】存储系统