二叉树数组C++实现

基本概念梳理

  1. 孩子:子结点
  2. 双亲:父节点
  3. 度:有多少个子结点
  4. 有序树:固定的排列的树
  5. 无序树:排列与顺序无关的树
  6. 二叉树:所有结点小于等于2的树

源代码:https://github.com/cjy513203427/C_Program_Base/tree/master/56.%E4%BA%8C%E5%8F%89%E6%A0%91%E6%95%B0%E7%BB%84%E5%AE%9E%E7%8E%B0

需要实现的方法

复制代码
#pragma once
#ifndef TREE_H
#define TREE_H

class Tree
{
public:
    Tree(int size,int *pRoot);//创建树
    ~Tree();//销毁树
    int *SearchNode(int nodeIndex);//根据索引寻找结点
    bool AddNode(int nodeIndex, int direction, int *pNode);//添加结点
    bool DeleteNode(int nodeIndex, int *pNode);//删除结点
    void TreeTraverse();//遍历
private:
    int *m_pTree;
    int m_iSize;
};

#endif // !TREE_H
复制代码

1.创建树

传入数组容量和根节点地址

m_iSize和m_pTree初始化

将数组都置为0初始化

pRoot指向的内存单元的树值赋值数组首元素(根元素)

复制代码
Tree::Tree(int size, int *pRoot)
{
    m_iSize = size;
    m_pTree = new int[m_iSize];
    for (int i = 0; i < m_iSize; i++)
    {
        m_pTree[i] = 0;
    }
    m_pTree[0] = *pRoot;
}
复制代码

 2.销毁树

删除指针并置空

Tree::~Tree()
{
    delete []m_pTree;
    m_pTree = NULL;
}

3.根据索引寻找结点

先判断索引的合法性,索引不能小于0或者大于等于长度

传入数组的值不能等于0

返回该数组地址

复制代码
int *Tree::SearchNode(int nodeIndex)
{
    if (nodeIndex<0 || nodeIndex>=m_iSize)
    {
        return NULL;
    }
    if (m_pTree[nodeIndex] == 0)
    {
        return NULL;
    }
    return &m_pTree[nodeIndex];
}
复制代码

4.添加结点

判断索引合法性,和3.一样

direction = 0代表添加左子节点,direction = 1代表添加右子节点

左子节点 = 2*索引+1;右子节点 = 2*索引+2

下图可以验证

继续判断索引的合法性,左子节点和右子节点同样不能小于0或者大于等于数组长度

最后将*pNode赋值给子节点

复制代码
bool Tree::AddNode(int nodeIndex, int direction, int *pNode)
{
    if (nodeIndex<0 || nodeIndex >= m_iSize)
    {
        return false;
    }
    if (m_pTree[nodeIndex] == 0)
    {
        return false;
    }
    if (direction == 0)
    {
        //nodeIndex * 2 + 1<0可以省略
        if (nodeIndex * 2 + 1<0 || nodeIndex * 2 + 1 >= m_iSize)
        {
            return false;
        }
        //判断是否有左子节点
        if (m_pTree[nodeIndex * 2 + 1] != 0)
        {
            return false;
        }
        m_pTree[nodeIndex * 2 + 1] = *pNode;
    }
    if (direction == 1)
    {
        //nodeIndex * 2 + 2<0可以省略
        if (nodeIndex * 2 + 2<0 || nodeIndex * 2 + 2 >= m_iSize)
        {
            return false;
        }
        //判断是否有左子节点
        if (m_pTree[nodeIndex * 2 + 2] != 0)
        {
            return false;
        }
        m_pTree[nodeIndex * 2 + 2] = *pNode;
    }
    return true;
}
复制代码

 5.删除结点

判断索引和数组值的合法性

将*pNode接收删除的对应索引的数组

将该索引数组置为0,结点值等于0代表删除

返回正确结果

复制代码
bool Tree::DeleteNode(int nodeIndex, int *pNode)
{
    if (nodeIndex<0 || nodeIndex >= m_iSize)
    {
        return false;
    }
    if (m_pTree[nodeIndex] == 0)
    {
        return false;
    }
    *pNode = m_pTree[nodeIndex];
    m_pTree[nodeIndex] = 0;
    return true;
}
复制代码

6.遍历

没啥好说的

void Tree::TreeTraverse()
{
    for (int i = 0; i < m_iSize; i++)
    {
        cout << m_pTree[i] << " ";
    }
}

 

posted @   Rest探路者  阅读(1914)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
levels of contents
点击右上角即可分享
微信分享提示