吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 838|回复: 1
收起左侧

[C&C++ 原创] C++实现BST,重载运算符,友元..【第四篇】

[复制链接]
仿佛_一念成佛 发表于 2024-6-16 03:53

C++实现BST,重载运算符,友元..【第四篇】

倒数第二篇,早在五月份就写完了但是要考试,现在六月中,已经考完。干脆直接写完这两篇

话不多说直接开干


这一次我们要实现一个二叉搜索树,然后重载一些运算符,最后实现一些友元函数。我首先声明了两个类,分别是TABBCalendario和TNodoABB。TABBCalendario是二叉搜索树的类,TNodoABB是二叉搜索树的节点类。

声明如下:

TNodoABB


{
    friend class TABBCalendario;

private:
    // Elemento del nodo
    TCalendario item;
    // Subárbol izquierdo y derecho
    TABBCalendario left, right;

public:
    // Constructor por defecto
    TNodoABB();
    // Constructor copia
    TNodoABB(const TNodoABB &);
    // Destructor
    ~TNodoABB();
    // Sobrecarga del operador asignación
    TNodoABB &operator=(const TNodoABB &);
};

TABBCalendario

class TABBCalendario
{
     // Sobrecarga del operador salida
    friend std::ostream &operator<<(std::ostream &, const TABBCalendario &);
    friend class TNodoABB;
private:
    // Puntero al nodo
    TNodoABB *raiz;
    // AUXILIAR: devuelve el recorrido en INORDEN
    void InordenAux(TVectorCalendario &, int &) const;
    // AUXILIAR: devuelve el recorrido en PREORDEN
    void PreordenAux(TVectorCalendario &, int &) const;
    // AUXILIAR: devuelve el recorrido en POSTORDEN
    void PostordenAux(TVectorCalendario &, int &) const;
    // Copia de un árbol
    void copyNode(const TNodoABB *);
    void deleteNode(TNodoABB *);
public:
    // Constructor por defecto
    TABBCalendario();
    // Constructor de copia
    TABBCalendario(const TABBCalendario &);
    // Destructor
    ~TABBCalendario();
    // Sobrecarga del operador asignación
    TABBCalendario &operator=(const TABBCalendario &);
    // Sobrecarga del operador igualdad
    bool operator==(const TABBCalendario &) const;
    // Devuelve TRUE si el árbol está vacío, FALSE en caso contrario
    bool EsVacio() const;
    // Inserta el elemento en el árbol
    bool Insertar(const TCalendario &); // Borra el elemento en el árbol
    bool Borrar(const TCalendario &);
    // Devuelve TRUE si el elemento está en el árbol, FALSE en caso contrario
    bool Buscar(const TCalendario &) const;
    // Devuelve el elemento de la raíz del árbol
    TCalendario Raiz() const;
    // Devuelve la altura del árbol (la altura de un árbol vacío es 0)
    int Altura() const;
    // Devuelve el número de nodos del árbol (un árbol vacío posee 0 nodos)
    int Nodos() const;
    // Devuelve el número de nodos hoja en el árbol (la raíz puede ser nodo hoja)
    int NodosHoja() const;
    // Devuelve el recorrido en INORDEN sobre un vector
    TVectorCalendario Inorden() const;
    // Devuelve el recorrido en PREORDEN sobre un vector
    TVectorCalendario Preorden() const;
    // Devuelve el recorrido en POSTORDEN sobre un vector
    TVectorCalendario Postorden() const;
    // Devuelve el recorrido en NIVELES sobre un vector
    TVectorCalendario Niveles() const;

    // Suma de dos ABB
    TABBCalendario operator+(const TABBCalendario &) const;
    // Resta de dos ABB
    TABBCalendario operator-(const TABBCalendario &) const;
    // ---------------------
    TVectorCalendario ABBCamino(TListaCalendario &l);
    TABBCalendario invertTree(const TABBCalendario &) const;
    void getCamino(const TCalendario &, TVectorCalendario &) const;
    // Binary Tree Level Order Traversal
    TVectorCalendario levelOrder() const;
    TCalendario findBottomLeftValue() const;
};

实现TNodoABB

节点
TNodoABB::TNodoABB()
{
    this->item = TCalendario();
    this->left = TABBCalendario();
    this->right = TABBCalendario();
}
// 深拷贝
TNodoABB::TNodoABB(const TNodoABB &tn)
{
    TNodoABB temp = tn;
    this->item = temp.item;
    this->left = temp.left;
    this->right = temp.right;
    temp.~TNodoABB();
}
// 析构
TNodoABB::~TNodoABB()
{
    this->item.~TCalendario();
    this->left.~TABBCalendario();
    this->right.~TABBCalendario();
}
// 赋值
TNodoABB &TNodoABB::operator=(const TNodoABB &tn)
{
    // when t = t
    if (this == &(tn))
    {
        return *this;
    }
    (*this).~TNodoABB();
    this->item = tn.item;
    this->left = tn.left;
    this->right = tn.right;
    return *this;
}

实现TABBCalendario

Inorden遍历

void TABBCalendario::InordenAux(TVectorCalendario &tv, int &i) const
{
    if (this->raiz == nullptr)
    {
        return;
    }
    this->raiz->left.InordenAux(tv, i);
    tv[i] = this->raiz->item;
    i++;
    this->raiz->right.InordenAux(tv, i);
}

Preorden遍历


void TABBCalendario::PreordenAux(TVectorCalendario &tv, int &i) const
{
    if (this->raiz == nullptr)
    {
        return;
    }
    tv[i] = this->raiz->item;
    i++;
    this->raiz->left.PreordenAux(tv, i);
    this->raiz->right.PreordenAux(tv, i);
}

Postorden遍历

void TABBCalendario::PostordenAux(TVectorCalendario &tv, int &i) const
{
    if (this->raiz == nullptr)
    {
        return;
    }
    this->raiz->left.PostordenAux(tv, i);
    this->raiz->right.PostordenAux(tv, i);
    tv[i] = this->raiz->item;
    i++;
}

构造函数

TABBCalendario::TABBCalendario() : raiz(nullptr) {}

深拷贝

TABBCalendario::TABBCalendario(const TABBCalendario &tAbb) 
{
    this->raiz = nullptr;
    copyNode(tAbb.raiz);
}
// copiar profundamente de cada nodo
void TABBCalendario::copyNode(const TNodoABB *tn)
{
    if(tn == nullptr)
    {
        return;
    }
    this->raiz = new TNodoABB();
    this->raiz->item = tn->item;
    this->raiz->left.copyNode(tn->left.raiz);
    this->raiz->right.copyNode(tn->right.raiz);
}

析构函数


TABBCalendario::~TABBCalendario() 
{
    this->raiz = nullptr;
    // deleteNode(this->raiz);
}
// borrar cada nodo
void TABBCalendario::deleteNode(TNodoABB *tn)
{
    if(tn == nullptr)
    {
        return;
    }
    tn->left.deleteNode(tn);
    tn->right.deleteNode(tn);
    delete tn;
    tn = nullptr;
}

赋值运算符


TABBCalendario &TABBCalendario::operator=(const TABBCalendario &tAbb)
{
    // when t = t
    if (this == &tAbb)
    {
        return *this;
    }
    (*this).~TABBCalendario();
    copyNode(tAbb.raiz);
    return *this;
}

等于运算符


bool TABBCalendario::operator==(const TABBCalendario &tAbb) const
{
    if(this->Inorden() == tAbb.Inorden())
    {
        return true;
    }

    return false;
} 

节点是否为空


bool TABBCalendario::EsVacio() const
{
    if (this->raiz == nullptr)
    {
        return true;
    }
    return false;
}

插入


bool TABBCalendario::Insertar(const TCalendario &tc)
{
    /*
    Procedimiento:
            comprobar que la raiz actual de this es vacio or no. Si lo es, insertar, si no lo es, resursividad.
            recursividad lo hace que comprobar varias veces si la raiz actual de this anterior es vacio o no. si lo es, insertar
    */
    if (this->raiz == nullptr)
    {
        this->raiz = new TNodoABB();
        this->raiz->item = tc;
        return true;
    }
    if (this->raiz->item == tc)
    {
        return false;
    }
    if (this->raiz->item > tc)
    {
        return this->raiz->left.Insertar(tc);
    }
    if (this->raiz->item < tc)
    {
        return this->raiz->right.Insertar(tc);
    }
    return false;
}

删除

bool TABBCalendario::Borrar(const TCalendario &tc)
{
    if (this->raiz == NULL)
    {
        return false;
    }

    if (this->raiz->item > tc)
    {
        return this->raiz->left.Borrar(tc);
    }

    else if (this->raiz->item < tc)
    {
        return this->raiz->right.Borrar(tc);
    }
    else
    {
        if (this->raiz->left.EsVacio() && this->raiz->right.EsVacio())
        {
            delete this->raiz;
            this->raiz = NULL;
            return true;
        }

        if (this->raiz->left.EsVacio() && !this->raiz->right.EsVacio())
        {
            TNodoABB *temp = this->raiz;
            this->raiz = this->raiz->right.raiz;
            temp->right.raiz = NULL;
            delete temp;
            return true;
        }

        if (!this->raiz->left.EsVacio() && this->raiz->right.EsVacio())
        {
            TNodoABB *temp = this->raiz;
            this->raiz = this->raiz->left.raiz;
            temp->left.raiz = NULL;
            delete temp;
            return true;
        }

        TNodoABB *temp = this->raiz->left.raiz;
        if (temp == NULL)
        {
            return false;
        }

        while (!temp->right.EsVacio())
        {
            temp = temp->right.raiz;
        }

        this->raiz->item = temp->item;
        this->raiz->left.Borrar(temp->item);
        return true;
    }
    return false;
}

查找


bool TABBCalendario::Buscar(const TCalendario &tc) const
{
    if (this->raiz == nullptr) // si no lo encuentra entonces return false
    {
        return false;
    }
    if (this->raiz->item == tc) // si lo encuentra entonces return true
    {
        return true;
    }

    if (this->raiz->item < tc) // si el item de la raiz es menor que el tc, entonces buscar en la derecha
    {
        return this->raiz->right.Buscar(tc);
    }
    if (this->raiz->item > tc) // si el item de la raiz es mayor que el tc, entonces buscar en la izquierda
    {
        return this->raiz->left.Buscar(tc);
    }
    return false;
}

根节点


TCalendario TABBCalendario::Raiz() const
{
    // un arbol solo tiene una raiz, si no lo hay, devolver un Tcalendario por defecto
    if (this->raiz != nullptr)
    {
        return this->raiz->item;
    }
    return TCalendario();
}

高度


int TABBCalendario::Altura() const
{
    if (this->raiz == nullptr)
    {
        return 0;
    }
    return 1 + std::max(this->raiz->left.Altura(), this->raiz->right.Altura());
}

节点数

int TABBCalendario::Nodos() const
{
    if (this->raiz == nullptr)
    {
        return 0;
    }
    return 1 + this->raiz->left.Nodos() + this->raiz->right.Nodos();
}

叶子节点数

int TABBCalendario::NodosHoja() const
{
    if (this->raiz == nullptr)
    {
        return 0;
    }
    if (this->raiz->left.raiz == nullptr && this->raiz->right.raiz == nullptr)
    {
        return 1;
    }
    return this->raiz->left.NodosHoja() + this->raiz->right.NodosHoja();
}

三大遍历

TVectorCalendario TABBCalendario::Inorden() const
{
    int pos = 1;
    TVectorCalendario v(Nodos());
    InordenAux(v, pos);
    return v;
}
// Devuelve el recorrido en PREORDEN sobre un vector
TVectorCalendario TABBCalendario::Preorden() const
{
    int pos = 1;
    TVectorCalendario v(Nodos());
    PreordenAux(v, pos);
    return v;
}
// Devuelve el recorrido en POSTORDEN sobre un vector
TVectorCalendario TABBCalendario::Postorden() const
{
    int pos = 1;
    TVectorCalendario v(Nodos());
    PostordenAux(v, pos);
    return v;
}

层次遍历

TVectorCalendario TABBCalendario::Niveles() const
{
    std::queue<TNodoABB *> q; // cola
    TVectorCalendario v(Nodos()); // crear un vector de tamanio de nodos
    int pos = 1;

    if (this->raiz != nullptr)
    {
        q.push(this->raiz);
    }

    while (!q.empty())
    {
        TNodoABB *temp = q.front(); // coger el primer elemento de la cola
        q.pop(); // borrar el primer elemento de la cola
        v[pos] = temp->item; // poner el item de ese nodo en el vector
        pos++; // aumentar la posicion
        if (temp->left.raiz != nullptr) // si el nodo tiene un hijo izquierdo, ponerlo en la cola
        {
            q.push(temp->left.raiz);
        }
        if (temp->right.raiz != nullptr) // si el nodo tiene un hijo derecho, ponerlo en la cola
        {
            q.push(temp->right.raiz);
        }
    }
    return v;
}

重载输出运算符

std::ostream &operator<<(std::ostream &os, const TABBCalendario &tabb)
{
    TVectorCalendario t = tabb.Niveles();

    return os << t;
}

重载加法运算符


TABBCalendario TABBCalendario::operator+(const TABBCalendario &tabb) const
{

    TABBCalendario temp = *this;
    TVectorCalendario v = tabb.Inorden();
    for (int i = 1; i <= v.Tamano(); i++)
    {
        temp.Insertar(v[i]);
    }
    return temp;

}

重载减法运算符


TABBCalendario TABBCalendario::operator-(const TABBCalendario &tabb) const
{
    TABBCalendario temp;
    TVectorCalendario _this = this->Inorden();
    for(int i = 1; i <= _this.Tamano(); i++)
    {
        if(!tabb.Buscar(_this[i]))
        {
            temp.Insertar(_this[i]);
        }
    }
    return temp;
}

// 左右互换

TABBCalendario TABBCalendario::invertTree(const TABBCalendario &t) const
{
    if(t.EsVacio())
    {
        return t;
    }
    TABBCalendario temp = t.raiz->left;
    t.raiz->left = t.raiz->right;
    t.raiz->right = temp;
    invertTree(t.raiz->left);
    invertTree(t.raiz->right);

    return t;
}

TVectorCalendario TABBCalendario::ABBCamino(TListaCalendario &tl)
{
    TVectorCalendario resultado;
    if(tl.EsVacia() || this->EsVacio())
    {
        return resultado;
    }

    TListaPos pos = tl.Primera();

    while(!pos.EsVacia())
    {
        if(!this->Buscar(tl.Obtener(pos)))
        {
            this->Insertar(tl.Obtener(pos));
            TCalendario c = tl.Obtener(pos);
            this->getCamino(c, resultado);
        }
        pos = pos.Siguiente();
    }
    for(TListaPos i = tl.Primera(); !i.EsVacia(); i = i.Siguiente())
    {
        if(!this->Buscar(tl.Obtener(i)))
        {
            this->Insertar(tl.Obtener(i));
            TCalendario c = tl.Obtener(i);
            this->getCamino(c, resultado);
        }
    }
    return resultado;
}

void TABBCalendario::getCamino(const TCalendario &c, TVectorCalendario &tv) const
{
    if(this->raiz == nullptr)
    {
        return;
    }
    if(this->raiz->item == c)
    {
        tv.Redimensionar(tv.Tamano() + 1);
        tv[tv.Tamano()] = this->raiz->item;

        return;
    }
    if(this->raiz->item > c)
    {
        tv.Redimensionar(tv.Tamano() + 1);
        tv[tv.Tamano()] = this->raiz->item;
        this->raiz->left.getCamino(c, tv);
    }
    if(this->raiz->item < c)
    {
        tv.Redimensionar(tv.Tamano() + 1);
        tv[tv.Tamano()] = this->raiz->item;
        this->raiz->right.getCamino(c, tv);
    }
    return;
}

TVectorCalendario TABBCalendario::levelOrder() const
{
    std::queue<TNodoABB *> q;
    TVectorCalendario v(Nodos());
    int pos = 1;

    if (this->raiz != nullptr)
    {
        q.push(this->raiz);
    }

    while (!q.empty())
    {
        TNodoABB *temp = q.front();
        q.pop();
        v[pos] = temp->item;
        pos++;
        if (temp->left.raiz != nullptr)
        {
            q.push(temp->left.raiz);
        }
        if (temp->right.raiz != nullptr)
        {
            q.push(temp->right.raiz);
        }
    }
    return v;
}

TCalendario TABBCalendario::findBottomLeftValue() const
{
    std::queue<TNodoABB *> q;
    TCalendario result;
    if (this->raiz != nullptr)
    {
        q.push(this->raiz);
    }

    while (!q.empty())
    {
        TNodoABB *temp = q.front();
        q.pop();
        result = temp->item;
        if (temp->right.raiz != nullptr)
        {
            q.push(temp->right.raiz);
        }
        if (temp->left.raiz != nullptr)
        {
            q.push(temp->left.raiz);
        }
    }
    return result;
}

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
fire9 发表于 2024-6-16 08:09
提示: 该帖被管理员或版主屏蔽
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 16:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表