第一步:定义栈

因为要中序遍历,所以要定义栈。

typedef struct Snode{
    BSTree data;
    struct Snode *next;
}Snode , *LinkStack;
//初始化
bool InitStack(LinkStack &s){
    s = NULL;
    return true;
}
//判断是否为空
bool Empty(LinkStack s){
    if(s == NULL) return true;
    return false;
}
//入栈
bool Push(LinkStack &s , BSTree e){
    LinkStack p = new Snode;
    p -> data = e;
    p -> next = s;
    s = p;
    return true;
}
//出栈
bool Pop(LinkStack &s , BSTree &e){
    if(Empty(s)) return false;
    e = s->data;
    LinkStack p = s;
    s = s->next;
    delete p;
    return true;
}
//取栈顶元素
BSTree GetTop(LinkStack s){
    return s->data;
}

第二步,定义二叉排序树的结构:

typedef struct
{
    int key;                  //关键字项
}ElemType;                     // 每个节点的数据类型
typedef struct BSTNode
{
    ElemType data;                      //每个节点的数据域包括关键字项和其他数据项
    struct BSTNode *lchild, *rchild;    // 左右孩子指针
}BSTNode , *BSTree;

第三步,查询树:

BSTree SearchBST (BSTree T , int key){
    if((!T) || key == T->data.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){
    //当二叉排序树T中不存在关键字等于e.key的数据元素时 ,则插入该元素
    if(!T){
        BSTree S = new BSTNode;        //生成新节点*S
        S->data = e;                   // 新节点*s的数据域置为e
        S->lchild = S->rchild = NULL;   // 新节点作为叶子节点
        T = S;                  // 把新节点*S连接到以找到的插入位置
    }
    else if(e.key < T->data.key) {
        InsertBST(T->lchild, e);
    }
    else if(e.key > T->data.key) {
        InsertBST(T->rchild, e);
    }
}

第五步,删除元素:

课本上是用中序遍历结果的前驱来替换被删除元素,我们用后继来替换

//删除
void DeleteBST(BSTree &T, int key){
    //从二叉排序树T中删除关键字等于key的节点
    BSTree p = T, f =NULL;//P为指向节点的指针f为指向双亲节点的指针
    BSTree s = new BSTNode;
    while(p){
        if(p->data.key == key ) break;
        f = p;
        if(p->data.key > key) p = p->lchild;
        else p = p->rchild;
    }
    
    if(!p) return ; // 找不到被删结点则返回
    BSTree q = new BSTNode;
    q = p;
    if((p->lchild) && (p->rchild))    // 被删节点*p左右字数均不为空
    {
        s = p->rchild;
        while(s->lchild){          //在*p的右子树中继续查找其后继节点,即最左下节点
            q = s;
            s = s->lchild;          //向左走到尽头;
        }
        p->data = s->data;              //s指向被删结点的“后继”
        if(q!=p) q->lchild = s->rchild;    // 重接q的左子树
        else q->rchild = s->rchild;         //重接q的右子树
        delete s;
        return;
    }
    else if (!p->rchild){
        p = p->lchild;
    }
    else if(!p->lchild){
        p = p->rchild;
    }
    
    if(!f)  T = p;
    else if(q == f->lchild) f->lchild = p;
    else f -> rchild = p;
    delete q;
    
}

第六步,创建树;

//创建
void CreatBST(BSTree &T){
    ElemType e;
    T = NULL;
    cin>> e.key;
    while(e.key !=ENDFLAG){
        InsertBST(T, e);
        cin>>e.key;
    }
}

第七步,中序遍历二叉树;

//中序遍历树
LinkStack s,s1,s2;
void InOrderTraverse (BSTree T) {
    InitStack(s);
    BSTree p = new BSTNode;
    p = T;
    BSTree q = new BSTNode;
//    BiTree q1 = new BiTNode;
    while(p || !Empty(s)){
        if(p) {
            Push(s,p);
            p = p ->lchild;
        }
        else {
            Pop(s,q);
            cout << q->data.key<<" ";
            p = q->rchild;
        }
    }
    cout << "\n";
}

完工!! 完整代码

//
//  main.cpp
//  第七次实验
//
//  Created by 宋玉良 on 2020/12/10.
//
#include<bits/stdc++.h>
#define ENDFLAG 0
using namespace std;

typedef struct
{
    int key;                  //关键字项
}ElemType;                     // 每个节点的数据类型
typedef struct BSTNode
{
    ElemType data;                      //每个节点的数据域包括关键字项和其他数据项
    struct BSTNode *lchild, *rchild;    // 左右孩子指针
}BSTNode , *BSTree;


typedef struct Snode{
    BSTree data;
    struct Snode *next;
}Snode , *LinkStack;
//初始化
bool InitStack(LinkStack &s){
    s = NULL;
    return true;
}
//判断是否为空
bool Empty(LinkStack s){
    if(s == NULL) return true;
    return false;
}
//入栈
bool Push(LinkStack &s , BSTree e){
    LinkStack p = new Snode;
    p -> data = e;
    p -> next = s;
    s = p;
    return true;
}
//出栈
bool Pop(LinkStack &s , BSTree &e){
    if(Empty(s)) return false;
    e = s->data;
    LinkStack p = s;
    s = s->next;
    delete p;
    return true;
}
//取栈顶元素
BSTree GetTop(LinkStack s){
    return s->data;
}
//中序遍历树
LinkStack s,s1,s2;
void InOrderTraverse (BSTree T) {
    InitStack(s);
    BSTree p = new BSTNode;
    p = T;
    BSTree q = new BSTNode;
//    BiTree q1 = new BiTNode;
    while(p || !Empty(s)){
        if(p) {
            Push(s,p);
            p = p ->lchild;
        }
        else {
            Pop(s,q);
            cout << q->data.key<<" ";
            p = q->rchild;
        }
    }
    cout << "\n";
}
//查找
BSTree SearchBST (BSTree T , int key){
    if((!T) || key == T->data.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){
    //当二叉排序树T中不存在关键字等于e.key的数据元素时 ,则插入该元素
    if(!T){
        BSTree S = new BSTNode;        //生成新节点*S
        S->data = e;                   // 新节点*s的数据域置为e
        S->lchild = S->rchild = NULL;   // 新节点作为叶子节点
        T = S;                  // 把新节点*S连接到以找到的插入位置
    }
    else if(e.key < T->data.key) {
        InsertBST(T->lchild, e);
    }
    else if(e.key > T->data.key) {
        InsertBST(T->rchild, e);
    }
}

//创建
void CreatBST(BSTree &T){
    ElemType e;
    T = NULL;
    cin>> e.key;
    while(e.key !=ENDFLAG){
        InsertBST(T, e);
        cin>>e.key;
    }
}
//删除
void DeleteBST(BSTree &T, int key){
    //从二叉排序树T中删除关键字等于key的节点
    BSTree p = T, f =NULL;//P为指向节点的指针f为指向双亲节点的指针
    BSTree s = new BSTNode;
    while(p){
        if(p->data.key == key ) break;
        f = p;
        if(p->data.key > key) p = p->lchild;
        else p = p->rchild;
    }
    
    if(!p) return ; // 找不到被删结点则返回
    BSTree q = new BSTNode;
    q = p;
    if((p->lchild) && (p->rchild))    // 被删节点*p左右字数均不为空
    {
        s = p->rchild;
        while(s->lchild){          //在*p的左子树中继续查找其前驱节点,即最左下节点
            q = s;
            s = s->lchild;          //向左走到尽头;
        }
        p->data = s->data;              //s指向被删结点的“后继”
        if(q!=p) q->lchild = s->rchild;    // 重接q的左子树
        else q->rchild = s->rchild;         //重接q的右子树
        delete s;
        return;
    }
    else if (!p->rchild){
        p = p->lchild;
    }
    else if(!p->lchild){
        p = p->rchild;
    }
    
    if(!f)  T = p;
    else if(q == f->lchild) f->lchild = p;
    else f -> rchild = p;
    delete q;
    
}
int main()
{
    BSTree T = new BSTNode;
    cout << "请输入创建节点的值(输入0)结束"<<endl;
    CreatBST(T);
    cout << "创建的二叉排序树为:"<< endl;
    InOrderTraverse(T);
    int n =3;
    while(n--){
        int Case;
        cout << "请输入操作序号,1查询,2插入,3删除" << endl;
        cin>>Case;
        if(Case == 3){
            cout << "请输入要删除的值"<<endl;
            int key;
            cin>>key;
            DeleteBST(T, key);
            cout << "二叉排序树为" << endl;
            InOrderTraverse(T);
        }
        else if(Case == 1){
            cout << "请输入要查询的值"  << endl;
            int key;
            cin >>key;
            if(SearchBST(T, key)){
                cout << "存在" << endl;
            }
            else cout << "不存在"<<endl;
        }
        else if(Case == 2){
            cout << "请输入要插入的值" << endl;
            BSTree key = new BSTNode;
            cin >> key->data.key;
            InsertBST(T, key->data);
            cout << "二叉排序树为" << endl;
            InOrderTraverse(T);
        }
    }
    cout << endl;
}