zoukankan      html  css  js  c++  java
  • C++二叉搜索树

    //BST.h
    #pragma once
    template <typename T> class BST;
    template <typename T> class BSTNode {
    public:
        friend class BST<T>;
        BSTNode() {
            lChild = rChild = parent = nullptr;
            data = nullptr;
        }
        BSTNode(T value) {
            lChild = rChild = parent = nullptr;
            data = value;
        }
    private:
        BSTNode<T>* lChild, * rChild, * parent;
        T data;
    };
    
    template<typename T> class BST {
    public:
        BST() { }
    
        //插入操作
        void insert(BSTNode<T>* node);
    
        //二叉查找树的中序遍历,就相当于排序了
        void inSort(BSTNode<T>* node);
    
        //按节点删除
        void deleteNode(BSTNode<T>* node);
    
        //按数值删除
        void deleteNode(const T& t);
    
        BSTNode<T>* search(T key);
        BSTNode<T>* root = nullptr;
    
    private:
        int count;
    };
    
    template<typename T>
    void BST<T>::insert(BSTNode<T>* node)
    {
        BSTNode<T>* curr, * temp = nullptr;
        curr = root;
        while (nullptr != curr) //遍历二叉树,找到应该插入的父节点
        {
            temp = curr;
            if (node->data > curr->data)
            {
                curr = curr->rChild;
            }
            else {
                curr = curr->lChild;
            }
        }
        node->parent = temp;//temp 代码当前最后遍历的node,设置node->parent为该节点
        if (temp == nullptr)
        {
            root = node;
            count++;
        }
        else {
            if (node->data < temp->data)
            {
                temp->lChild = node;
                count++;
            }
            else {
                temp->rChild = node;
                count++;
            }
        }
    }
    
    template<typename T>
    void BST<T>::inSort(BSTNode<T>* node)
    {
        if (node != nullptr)
        {
            inSort(node->lChild);
            std::cout << node->data << ",";
            inSort(node->rChild);
        }
    }
    
    template<typename T>
    inline void BST<T>::deleteNode(BSTNode<T>* node)
    {
        BSTNode<T>* p = node->parent;//获取node的父节点,这里很重要
        if (node->lChild == nullptr && node->rChild == nullptr) //叶子节点直接删除
        {
            if (node == node->parent->lChild)
            {
                node->parent->lChild = nullptr;
            }
            else {
                node->parent->rChild = nullptr;
            }
            delete node;
            count--;
        }
        else if (node->rChild != nullptr && node->lChild == nullptr) {//存在右孩子
            if (p == nullptr)//说明节点为根节点
            {
                root = node->rChild;
                count--;
            }
            else {
                node->rChild->parent = p;
                if (p->lChild == node) //判断是父节点的左孩子还是右孩子
                {
                    p->lChild = node->rChild;
                }
                else {
                    p->rChild = node->rChild;
                }
                delete node;
                count--;
            }
        }
        else if (node->lChild != nullptr && node->rChild == nullptr)//存在左孩子
        {
            if (p == nullptr)
            {
                root = root->lChild;
                count--;
            }
            else {
                node->lChild->parent = p;
                if (p->lChild == node)
                {
                    p->lChild = node->lChild;
                }
                else {
                    p->rChild = node->lChild;
                }
                delete node;
                count--;
            }
        }
        else {
            BSTNode<T>* left, * curp = nullptr;
            left = node->rChild; //本方案是找右侧最小值,替换node节点,其他节点保持不动即可
            while (left != nullptr)
            {
                curp = left;
                left = left->lChild;
            }
    
            if (curp->rChild != nullptr)
            {
                if (curp->lChild == curp)
                {
                    curp->parent->lChild = curp->rChild;
                }
                else {
                    curp->parent->rChild = curp->rChild;
                }
            }
            else {
                if (curp->parent->lChild == curp)
                {
                    curp->parent->lChild = nullptr;
                }
                else {
                    curp->parent->rChild = nullptr;
                }
                //curp->parent->lChild = nullptr;
            }
            //替curp 替换 node
            curp->parent = p;
            curp->lChild = node->lChild;
            curp->rChild = node->rChild;
    
            if (p->lChild == node)//判断node 是p 的左孩子还是右孩
            {
                p->lChild = curp;
            }
            else {
                p->rChild = curp;
            }
            delete node;
            count--;
        }
    }
    
    template<typename T>
    inline void BST<T>::deleteNode(const T& k)
    {
        BSTNode<T>* node = search(k);
        if (node != nullptr)
        {
            deleteNode(node);
        }
    }
    
    
    template<typename T>
    inline BSTNode<T>* BST<T>::search(T k)
    {
        BSTNode<T>* node = root;
        while (node != nullptr)
        {
            if (k < node->data)
            {
                node = node->lChild;
            }
            else if (k > node->data)
            {
                node = node->rChild;
            }
            else {
                break;
            }
        }
        return node;
    }
    
    //BSTree.h
    
    //BST.cpp
    #include "BST.h"
    
    //main.cpp
    //https://www.cnblogs.com/clc2008/p/10193550.html
    //#include "pch.h"
    #include <iostream>
    #include "BST.h"
    using namespace std;
    
    int main()
    {
        // 树结构示意
        //     30
        //    /  
        //  15   25
        // /  
        //9    18
        //   /   
        //  16   25
        //      /  
        //    20    26  
        BST<int> sbt;
        sbt.insert(new BSTNode<int>(30));
        sbt.insert(new BSTNode<int>(15));
        sbt.insert(new BSTNode<int>(9));
        sbt.insert(new BSTNode<int>(18));
        sbt.insert(new BSTNode<int>(16));
        sbt.insert(new BSTNode<int>(25));
        sbt.insert(new BSTNode<int>(20));
        sbt.insert(new BSTNode<int>(26));
        sbt.insert(new BSTNode<int>(35));
    
        cout << "搜索树排序后:";
        sbt.inSort(sbt.root);
    
        sbt.deleteNode(18);
    
        cout << endl << "删除18 后排序:";
    
        sbt.inSort(sbt.root);
    }
    
  • 相关阅读:
    java 泛型 类型作为参量 Class<T> transform
    面向对象的类方法只具有命名空间的作用
    编程语言沉思录—编程语言的体系结构
    类型约束的作用
    函数重载、多态与型变
    函数类型与型变
    型变(逆变)函数
    scala 型变
    泛型编程的几个关键概念
    泛型是包含类型参数的抽象类型—类型构造器
  • 原文地址:https://www.cnblogs.com/liutongqing/p/13597786.html
Copyright © 2011-2022 走看看