7.数据结构与算法--树(二叉树)

本文详细介绍了二叉树的概念,包括定义、特点、五种基本形态,特别是完全二叉树的定义和特点。此外,还深入探讨了二叉树的性质,如层序遍历、前序遍历、中序遍历和后序遍历的规则,并给出了建立二叉树节点及遍历算法的思路。
摘要由CSDN通过智能技术生成

1.二叉树

1.1二叉树定义

1.2二叉树定特点

1.2二叉树定五种基本的形态

 

1.3特殊二叉树

  • 斜树:单边斜,

  • 满二叉树

  • 完全二叉树

完全二叉树的定义:若设二叉树的高度为h,除第h层外,其它各层(1~h-1)的结点数都达到最大个数且第h层所有的节点都连续集中在最左边,这就是完全二叉树。

完全二叉树的特点:

2.二叉树的性质

  1. 在二叉树的第i层上至多有2^(i-1)个节点(i>=1)

  2. 深度为k的二叉树至多有  2^k-1 个节点  (k>=1)

  3. 对于任意一棵树T, 如果叶节点数量有n0个,度为2的节点数量有n2个,则n0=n2+1

推导过程: 假设度为1的节点个数为n1,那么树T的总结点数量为:n=n0+n2+n1;

从连接线的角度来看,总连接线数目 = 总结节点数-1 ,即 n-1; 而且总连接线数量 = n1 + 2*n2  (n1条线 + 度为2的节点必然拥有2个连接线);

那么有:n-1= n1 + 2*n2

所以:n0+n2+n1-1 = n1 +2 *n2

最后:n0 = n2+1

2.1二叉树的存储结构(顺序存储结构链式存储结构

  • 二叉树顺序存储结构(二叉树直接用一个数组存储即可)

  • 二叉树链式存储结构(二叉树直接用节点)

二叉树链表节点代码结构

 

2.1二叉树的遍历

  • 前提:限定为从左至右访问

  • 前序遍历规则:若为二叉树,则空操作返回,否则,先访问双亲节点,先前序遍历左子树,再前序遍历右子树 (即:双亲节点-->左子树 --> 右子树)。遍历顺序如下:

 

  • 中序遍历规则:若为二叉树,则空操作返回,先 访问双亲节点的左子树,然后访问双亲节点,最后访问右子树    (即:左节点--> 双亲节点--->右节点)。遍历顺序如下:

第7步小心:因为F没有左节点,

 

  • 后序遍历规则:若为二叉树,则空操作返回,否则,从最左边的子节点开始, 从左到右的方式遍历左右子树,最后访问双亲节点。遍历顺序如下:

  • 层序遍历:若为二叉树,则空操作返回,否则从树的第一层(即根节点开始) 从上而下逐层遍历,在同一层中,按从左到右的顺序对节点逐个访问。遍历顺序如下:

 

 

3.二叉树的建立与遍历算法

  • 建立二叉树节点:包括数据域,左指针,右指针

  • 创建一个二叉树

思路:

  1. 函数输入参数:树节点地址的引用
  2. 输入节点的data,以‘#’作为递归的结束方式
  3. 否则给节点创建一个内存空间,给节点的data赋值,递归左节点,再递归右节点

 

  1. 前序遍历二叉树

思路:

  1. 以节点等于NULL为结尾
  2. 输出根节点的data
  3. 递归遍历左子树
  4. 递归遍历右子树

  1. 中序遍历二叉树

思路:

  1. 以节点等于NULL为结尾
  2. 递归遍历左子树
  3. 输出根节点的data
  4. 递归遍历右子树
  1. 后序遍历二叉树

思路:

  1. 以节点等于NULL为结尾
  2. 递归遍历左子树
  3. 递归遍历右子树
  4. 输出根节点的data

 

完整代码:

在指针的语法上要注意:

在写函数参数 void creTree(Tnode* &T)   //参数编写,这里要特别小心   Tnode* &T

Tnode * T; 是定义了一个Tnode类型的指针T,;

creTnode(T); //给函数传入一个地址

#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
class Tnode
{
public:
    char data;
    Tnode* lnext;
    Tnode* rnext;
};
void creTree(Tnode* &T) //注意,这里的参数,不是直接传入地址,而是传入地址的引用!!否则会无法访问T地址
{
    char c;
    cin >> c;
    if (c == '#') //递归结束标志
    {
        T = NULL; //将树的叶节点赋值NULL
    }
    else
    {
        T = (Tnode*)malloc(sizeof(Tnode));
        T->data = c;
        creTree(T->lnext);
        creTree(T->rnext);
    }
}
void PreTrav(Tnode* &T)//注意,这里的参数,不是直接传入地址,而是传入地址的引用!!否则会无法访问T地址,前序遍历输出
{
    if (T)
    {
        cout << T->data;
        PreTrav(T->lnext);
        PreTrav(T->rnext);
    }
}

int main()
{
    std::cout << "Hello World!\n";
    Tnode* T;
    //前序遍历二叉树的方式进行输入:测试例子AB#CD##E##F#GH###
    creTree(T);
    PreTrav(T);
}

对应的二叉树为:

输出结果:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值