临近考试,这里先只发一下代码,关于定义,原理什么的等我有时间了会补充上。

#include <iostream>
#include <string>
using namespace std;
typedef int KeyType;    // 关键字类型
typedef string InfoType;    // 其他数据类型


typedef struct ElemType
{
    KeyType key;    // 关键字项
    InfoType info;  // 其他信息项
    // friend ElemType operator >> ( std::istream in, ElemType e)   // 想重载一下,结果发现没效果
    // {
    //     in >> e.key;
    //     in >> e.info;
    // }
} ElemType;         // 每个结点的类型
typedef struct BSTNode
{
    ElemType data;  // 数据域
    struct BSTNode *lchild, *rchild;    // 左右子节点指针
} BSTNode, *BSTree;

BSTree SearchBST(BSTree T, KeyType key)
{
    if( !T || T->data.key == key)       // 空树或者根节点是所查节点
        return T;
    else if(key < T->data.key)
        return SearchBST(T->lchild, key);   // 向左递归查找
    else
        return SearchBST(T->rchild, key);   // 向右递归查找
}
void InsertBST(BSTree &T, ElemType e)
{
    if( !T)
    {
        BSTree s = new BSTNode;     // 带插入节点
        s->data = e;
        s->lchild = s->rchild = NULL;
        T = s;
    }
    else if(e.key < T->data.key)
        InsertBST(T->lchild, e);    // 调用插入函数
    else
        InsertBST(T->rchild, e);
}
void CreatBST(BSTree &T)
{
    T = NULL;
    ElemType e;
    while(cin >> e.key)     // 输入文件结束符终止
    {
        InsertBST(T, e);
    }
}
void DeleteBST(BSTree &T, KeyType key)
{
    BSTree p = T;   // p为待删除节点
    BSTree f = NULL;    // f为带删除节点的双亲结点
    while(p)      // 查找的非递归写法
    {
        if(p->data.key == key)  // 找到关键字等于key的结点,结束循环
            break;
        f = p;                  // f是待删除结点的父节点
        if(key < p->data.key)   // 在左子树中继续寻找
            p = p->lchild;      
        else
            p = p->rchild;      // 在右子树中继续寻找
    }
    if(!p)  return;     // 没有查找到
    
    BSTree tmp = p;   // 先用tmp保存待删除结点
    if((p->lchild) && (p->rchild))  // 左右子树都存在
    {
        BSTree s = p->lchild;
        while(s->rchild)    /// 在*p的左子树中继续寻找其直接前驱,即最右下结点
        {
            tmp = s;        // 这里tmp是s的父节点
            s = s->rchild;
        }
        p->data = s->data;          // 把*p的前驱结点放到p处,然后删除前驱结点
        if(tmp != p)      // 如果相等了,说明p结点的左子树没有右子树
            tmp->rchild = s->lchild;    // s->lchild可能是一个子树,也可能是NULL
        else
            tmp->lchild = s->lchild;
        delete s;
        return;
    }
    else if( !p->rchild) //被删除结点没有右子树,只需要重接其左子树
        p = p->lchild;
    else if( !p->lchild) //被删除结点没有左子树,只需要重接其右子树
        p = p->rchild;    


    // 修改被删除结点父节点指针的指向
    if(!f)      // 被删除结点是根结点
        T = p;
    else if(tmp == f->lchild)   // 挂接到*f的左子树,被删除结点是被删除结点的父节点的左子树
        f->lchild = p;
    else                        // 挂接到*f的右子树
        f->rchild = p;
    delete tmp;
}

int main()
{
    BSTree T;
    CreatBST(T);

    BSTree t1 = SearchBST(T, 10);
    if(t1)
        cout << t1->data.key << endl;
    DeleteBST(T, 10);
    BSTree t2 = SearchBST(T, 10);
    if(t2)
        cout << t2->data.key << endl;
    else
        cout << "Not Find" << endl;




    return 0;
}