数据结构与算法:利用数组实现完全二叉树(C++)

任务:使用C++语言,通过数组的形式来实现一颗平衡二叉树,包括树的创建,添加结点,查找结点,删除结点等功能。

main.cpp 代码如下:

#include "CompleteBinaryTree.h"

int main()
{
    CompleteBinaryTree tree;
    for (int i = 0; i < 10; i++)
    {
        tree.Add('A' + i);
    }

    cout << "先序遍历:";
    tree.PreTravel();
    cout << endl;

    cout << "A的父结点为:";
    cout << tree.FindParent('A') << endl << endl;

    cout << "E的父结点为:";
    cout << tree.FindParent('E') << endl << endl;

    cout << "B的右孩子为:";
    cout << tree.FindRightChild('B') << endl << endl;

    cout << "D的左孩子为:";
    cout << tree.FindLeftChild('D') << endl << endl;

    cout << "F的左孩子为:";
    cout << tree.FindLeftChild('F') << endl << endl;

    cout << "K的左孩子为:";
    cout << tree.FindLeftChild('K') << endl << endl;

    tree.Delete('D');
    cout << "先序遍历:";
    tree.PreTravel();

    while (1);
    return 0;
}

CompleteBinaryTree.h 代码如下:

#pragma once
#include 

using namespace std;

template
class CompleteBinaryTree
{
    T*      pRoot;
    int  num;

public:

    //构造函数与析构函数
    CompleteBinaryTree();
    ~CompleteBinaryTree();


    //在二叉树尾部添加结点
    void Add(const T& data);

    //查找结点的父结点
    T FindParent(const T& data);

    //查找结点的左孩子积点
    T FindLeftChild(const T& data);

    //查找结点的右孩子结点
    T FindRightChild(const T& data);

    //删除结点
    void Delete(const T& data);

public:
    //先序遍历
    void PreTravel();

private:
    //先序遍历,递归用
    void _pretravel(int index);

    //获取结点编号
    int _getindex(const T& data);

};



//构造函数和析构函数
template
CompleteBinaryTree::CompleteBinaryTree()
{
    pRoot = NULL;
    num = 0;
}

template
CompleteBinaryTree::~CompleteBinaryTree()
{
    if (pRoot)
    {
        delete[] pRoot;
    }
}


//在二叉树尾部添加结点
template
void CompleteBinaryTree::Add(const T& data)
{
    //新开内存
    T* pTemp = new T[num + 1];

    //如果当前树不为空,将当前树中的结点拷贝至新开内存中,并且释放当前pRoot内存段
    if (pRoot)
    {
        memcpy(pTemp, pRoot, sizeof(T) * num);
        delete[] pRoot;
    }

    //pRoot指向新内存段,且将新增结点数据赋值给内存段的末尾,完成添加
    pRoot = pTemp;
    pRoot[num++] = data;
}



//查找结点的父结点
template
T CompleteBinaryTree::FindParent(const T& data)
{
    int index = _getindex(data);
    if (index < 0)
    {
        cout << "ERROR:没有找到该结点 ";
        return NULL;
    }

    //如果结点为根结点,则没有父结点
    if (index == 0)
    {
        cout << "该结点为根结点";
        return NULL;
    }

    //根据完整二叉树的性质,如果将二叉树从上至下,从左至右依次保存入一个数组中
    //已知结点的下标为index,则其父结点的下标为 (index - 1) / 2
    return pRoot[(index - 1) / 2];
}

//查找结点的左孩子结点
template
T CompleteBinaryTree::FindLeftChild(const T& data)
{
    int index = _getindex(data);
    if (index < 0)
    {
        cout << "ERROR:没有找到该结点 ";
        return NULL;
    }

    //根据完整二叉树的性质,如果将二叉树从上至下,从左至右依次保存入一个数组中
    //已知结点的下标为index,则其左孩子结点的下标为 index * 2 + 1
    index = index * 2 + 1;
    if (index < num)
    {
        return pRoot[index];
    }
    cout << "该结点没有左孩子";
    return NULL;
}

//查找结点的右孩子结点
template
T CompleteBinaryTree::FindRightChild(const T& data)
{
    int index = _getindex(data);
    if (index < 0)
    {
        cout << "ERROR:没有找到该结点 ";
        return NULL;
    }

    //根据完整二叉树的性质,如果将二叉树从上至下,从左至右依次保存入一个数组中
    //已知结点的下标为index,则其左孩子结点的下标为 index * 2 + 2
    index = index * 2 + 2;
    if (index < num)
    {
        return pRoot[index];
    }
    cout << "该结点没有右孩子";
    return NULL;
}


//删除结点
template
void CompleteBinaryTree::Delete(const T& data)
{
    int index = _getindex(data);
    if (index < 0)
    {
        cout << "ERROR:没有找到该结点 ";
       return;
    }

    //开劈新内存
    T* pNew = new T[num - 1];

    //将原树中的数据(除被删除的结点外)拷贝至新内存中
    memcpy(pNew, pRoot, sizeof(T) * index);
    if (index < num)
    {
        memcpy(pNew + index, pRoot + index + 1, sizeof(T) * (num - index - 1));
    }

    //释放原内存,将pRoot指向新内存空间
    delete[] pRoot;
    pRoot = pNew;
    num--;

    cout << "删除成功:" << data << endl;
}

//先序遍历
template
void CompleteBinaryTree::PreTravel()
{
    if (num <= 0)
    {
        cout << "ERROR:当前树为空!" << endl;
    }
    _pretravel(0);

    cout << endl;
}

//先序遍历,递归用
template
void CompleteBinaryTree::_pretravel(int index)
{
    if (index >= num)  return;

    //先遍历父结点,后依次遍历左右孩子结点
    cout << pRoot[index] << " ";

    //根据完整二叉树的性质,如果将二叉树从上至下,从左至右依次保存入一个数组中
    //已知父结点的下标为index,则其左孩子结点下标为index*2+1,右孩子结点下标为index*2+2 
    _pretravel(index * 2 + 1);
    _pretravel(index * 2 + 2);
}


//获取结点编号
template
int CompleteBinaryTree::_getindex(const T& data)
{
    if (pRoot == NULL)
        return -1;
    int index = 0;
    while (index

程序运行结果如下图:

数据结构与算法:利用数组实现完全二叉树(C++)_第1张图片

 

你可能感兴趣的:(数据结构与算法(C++),二叉树,c++,算法,数据结构)