C++数据结构第54课、树中结点的插入操作

  • 插入的方式应分为两种:
    — 插入新结点:bool insert(TreeNode<T>* node)
    — 插入数据元素:bool insert(const T& value, TreeNode<T>* parent)

  • 如何在树中指定新结点的位置?
    — 树是非线性的,无法采用下标的形式定位数据元素
    — 每一个树结点都有唯一的前驱结点(父结点)
    — 因此,必须先找到前驱节点,才能完成新结点的插入

在这里插入图片描述
插入新结点的流程:

在这里插入图片描述
插入数据元素流程:
在这里插入图片描述
GTreeNode.h

#ifndef GTREENODE_H
#define GTREENODE_H

#include "LinkList.h"
#include "TreeNode.h"

namespace XiebsLib
{

template <typename T>
class GTreeNode : public TreeNode<T>
{
public:
    LinkList<GTreeNode<T>*> child;

};
}
#endif // GTREENODE_H

GTree.h

    bool insert(TreeNode<T>* node)
    {
        bool ret = true;
        if(node != nullptr)
        {
            if(this->m_root == nullptr)        //判断根结点是否为空
            {
                node->parent = nullptr;
                this->m_root = node;
            }
            else
            {
                GTreeNode<T>* np = find(node->parent);        //先查找父结点在不在

                if(np != nullptr)
                {
                    GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);

                    if(np->child.find(n) < 0)        //防止反复插入父节点
                    {
                        np->child.insert(n);        //在父节点子类链表里面插入结点
                    }
                }
                else
                {
                    THROW_EXCEPTION(InvalidOperationException, "Invalid parent tree node");
                }
            }
        }
        else
        {
            THROW_EXCEPTION(InvalidParameterException, "parameter node cannot be null");
        }
        return ret;
    }

    bool insert(const T& value, TreeNode<T>* parent)
    {
        bool ret = true;
        GTreeNode<T>* node = new GTreeNode<T>();
        if(node != nullptr)
        {
            node->value = value;
            node->parent = parent;

            insert(node);
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "no memory to create new tree node");
        }
        return ret;
    }

main.cpp

#include <iostream>
#include "GTree.h"

using namespace std;
using namespace XiebsLib;

int main()
{
    GTree<char> t;
    GTreeNode<char>* node = nullptr;

    t.insert('A', nullptr);
    node = t.find('A');

    t.insert('B', node);
    t.insert('C', node);
    t.insert('D', node);

    node = t.find('B');
    t.insert('E', node);
    t.insert('F', node);

    node = t.find('E');
    t.insert('K', node);
    t.insert('L', node);

    node = t.find('C');
    t.insert('G', node);

    node = t.find('G');
    t.insert('N', node);

    node = t.find('D');
    t.insert('H', node);
    t.insert('I', node);
    t.insert('J', node);

    node = t.find('H');
    t.insert('M', node);

    const char* s = "KLFNMIJ";
    for(int i = 0; i < 7; i++)
    {
        TreeNode<char>* node = t.find(s[i]);

        while( node != nullptr )
        {
            cout << node->value << " ";

            node = node->parent;
        }

        cout << endl;
    }
    return 0;
}

在这里插入图片描述
小结:
1、插入操作是构建树的唯一操作
2、构建插入操作时必须指明结点间的父子关系
3、插入操作必须正确处理指向父结点的指针
4、插入数据元素是需要从堆空间中创建结点

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值