Fork me on GitHub

2019.6.24-2019.6.28(实训数据结构) 6.二叉排序树操作程序

2019.6.24-2019.6.28(实训数据结构) 书籍:《数据结构项目实训教程》 赵君喆,戴文华

9.2.1二叉排序树

要求开发一个二叉排序树的操作程序,要求程序至少具备以下操作接口:

初始化、销毁、查找、插入、删除、遍历

#include<cstdio>
#include<stdlib.h>
#include<string.h>
//#include<cunity>
#include<iostream>
#include<string>
#include<fstream>
#include<iomanip>
#include<algorithm>
using namespace std;
#define N 10  
typedef int KeyType; 
typedef int Status;
typedef struct{
    KeyType key;
    int others;
}ElemType;  //数据元素类型

typedef ElemType TElemType;

typedef struct BiTNode{
    TElemType data;
    struct BiTNode *lchild,*rchild;  //左右孩子指针 
}BiTNode, *BiTree;  //二叉树的二叉链表存储表示 
 
 
#define        EQ(a, b)        ((a) == (b))
#define        LT(a, b)        ((a) < (b))
#define        LQ(a, b)        ((a) <= (b))
 
#define InitDSTable InitBiTree  //与初始化二叉树操作同 
#define DestroyDSTable DestroyBiTree //与销毁二叉树操作同 
#define TraverseDSTable InOrderTraverse  //与中序遍历操作同

Status InitBiTree(BiTree &T){
    T=NULL;
    return true;
} 

void DestroyBiTree(BiTree &T){
    if(T){
        if(T->lchild)
            DestroyBiTree(T->lchild);
        if(T->rchild)
            DestroyBiTree(T->rchild);
        free(T);
        T=NULL;
    }
}

Status BiTreeEmpty(BiTree T){
    if(T)
        return false;
    else
        return true;
} 
//中序遍历 
void InOrderTraverse(BiTree T,void(*Visit)(TElemType)){
    if(T){
        InOrderTraverse(T->lchild,Visit);  //先中序遍历左子树
        Visit(T->data);  //再中序访问根结点
        InOrderTraverse(T->rchild,Visit);  // 最后中序遍历右子树 
    }
    printf("\n"); 
}

// 初始条件:二叉树T存在,Visit是对结点操作的应用函数
// 操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次
void PostOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ 
    if(T) // T不空
       {
         PostOrderTraverse(T->lchild,Visit); // 先后序遍历左子树
         PostOrderTraverse(T->rchild,Visit); // 再后序遍历右子树
         Visit(T->data); // 最后访问根结点
       }
}
 
// 初始条件:二叉树T存在,Visit是对结点操作的应用函数
// 操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次
void PreOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ 
    if(T) // T不空
       {
           Visit(T->data); // 先访问根结点
         PreOrderTraverse(T->lchild,Visit); // 再先序遍历左子树
         PreOrderTraverse(T->rchild,Visit); // 最后先序遍历右子树
         
       }
}
 
 

Status SearchBST(BiTree &T,KeyType key,BiTree f,BiTree &p){
    /*在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找
    成功,则指针p指向该数据元素结点,并返回TRUE,否则指针p指向查找路径上
    访问的最后一个结点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL*/
    if(!T){  //查找不成功 
        p=f;
        return false;
    }
    else if EQ(key,T->data.key){  // 查找成功 
        p=T;
        return true;
    }
    else if LT(key,T->data.key){  // 在左子树中继续查找 
        return SearchBST(T->lchild,key,T,p); 
    } 
    else{  // 在右子树中继续查找
        return SearchBST(T->rchild,key,T,p);  
    }
} 

BiTree SearchBST(BiTree T,KeyType key){
    /*在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素,
    若查找成功,则返回指向该数据元素结点的指针,否则返回空指针*/
    if(!T||EQ(key,T->data.key))
        return T;  //查找结果
    else if(LT(key,T->data.key))  //在左子树中继续寻找 
        return SearchBST(T->lchild,key); 
    else  //在右子树中继续寻找
        return SearchBST(T->rchild,key); 
} 

Status InsertBST(BiTree &T,ElemType e){
    /*当二叉排序树T不存在关键字等于e.key的数据元素时,
    插入e并返回TRUE,否则返回FALSE*/
    BiTree p,s;
    if(!SearchBST(T,e.key,NULL,p)){  // 查找不成功 
        s=(BiTree)malloc(sizeof(BiTNode));
        s->data=e;
        s->lchild=s->rchild=NULL;
        if(!p)
            T=s;  //被插入的结点*s为新的根结点
        else if LT(e.key,p->data.key)
            p->lchild=s;  //被插入的结点*s为左孩子
        else
            p->rchild=s;  //被插入的结点*s为右孩子
        return true; 
    } 
    else
        return false;  //树中已有关键字相同的结点,不再插入 
}



void Delete(BiTree &p){
    //从二叉排序树中删除结点p,并重接它的左或右子树
    BiTree q,s;
    if(!p->rchild){  //p的右子树空,只需重接它的左子树 
        q=p;
        p=p->lchild;
        free(q);
    } 
    else if(!p->lchild){  //p的左子树空,只需重接它的右子树
        q=p;
        p=p->rchild;
        free(q) ;
    } 
    else{  //p的左右子树均不为空 
        q=p;
        s=p->lchild;
        while(s->rchild){  //转左,然后向右直到尽头 
            q=s;
            s=s->rchild;
        } 
        p->data=s->data;  //s指向被删除结点的"前驱 "
        if(q!=p){  //情况1 
            q->rchild=s->lchild;  //重接q的右子树 
        }
        else{  //情况2 
            q->lchild=s->lchild;  //重接q的左子树 
        } 
        free(s);
    }
} 

Status DeleteBST(BiTree &T,KeyType key){
    /*若二叉排序树T中存在关键字等于key的数据元素,
    则删除该数据元素结点,并返回true;否则返回false*/
    if(!T)
        return false;  //不存在关键字等于key的数据元素 
    else{
        if EQ(key,T->data.key)
            Delete(T);  //找到关键字等于Key的元素
        else if LT(key,T->data.key)
            DeleteBST(T->lchild,key);
        else
            DeleteBST(T->rchild,key);
        return true; 
    }
} 

void print(ElemType c){
       printf("(%d,%d) ",c.key,c.others);
}
int main(){
    int choose;
    BiTree dt,p;
    int i,n;
    KeyType j; 
    ElemType r[N]={{45,1},{12,2},{53,3},{3,4},{37,5},{24,6},{100,7},{61,8},{90,9},{78,10}};
    cout<<"                           欢迎来到二叉树排序操作程序!!!!!" <<endl; 
    cout<<"                                请按以下数字操作" <<endl; 
    cout<<"----------------------------------1.初始化----------------------------------"<<endl;
    cout<<"----------------------------------2.销毁----------------------------------"<<endl;
    cout<<"----------------------------------3.插入------------------------------------"<<endl;
    cout<<"----------------------------------4.查找------------------------------------"<<endl;
    cout<<"----------------------------------5.删除----------------------------------"<<endl;
    cout<<"----------------------------------6.遍历--------------------------------------"<<endl;
    cout<<"----------------------------------0.退出程序------------------------------------"<<endl<<endl;
    choose=-1;
    while(choose!=0){
        cout<<"--------------------------------------------------------------------------------"<<endl;
        cout<<"请选择:"<<endl;
        cin>>choose; 
        switch(choose){
            case 0:                       
                cout<<"您已经成功退出系统,欢迎您下次再来!"<<endl;
            break;
            case 1: 
                InitDSTable(dt); 
                cout<<"您已经成功初始化!"<<endl;                     
            break;
            case 2: 
                DestroyDSTable(dt);
                printf("您已经成功销毁二叉排序树!\n");                      
            break;
            case 3:
                int n ;
                /*printf("请输入要插入的元素个数:\n");
                //scanf("%d",&n); 
                //ElemType r[n]={};
                printf("请依次输入要插入元素的关键字和变量:\n");
                //for(i=0;i<n;i++){
                //    cin>>r[i].key>>r[i].others;
                //}*/
                for(i=0;i<N;i++)
                     InsertBST(dt,r[i]);  
                printf("您已经成功插入元素!\n");                    
            break;
            case 4: 
                printf("请输入要查找的值:\n");
                scanf("%d",&j);
                   p=SearchBST(dt,j);
                   if(p) 
                    printf("表中存在此值。\n");
                   else
                     printf("表中不存在此值。\n");                     
            break;
            case 5: 
                printf("请输入要删除的元素:\n");
                scanf("%d",&j);
                   p=SearchBST(dt,j);
                   if(p){
                       printf("表中存在此值,可以删除。\n");
                       DeleteBST(dt,j);
                       printf("删除此值后:\n");
                    TraverseDSTable(dt,print);
                    printf("\n");
                }  
                   else
                     printf("表中不存在此值,无法删除。\n");                     
            break;
            case 6: 
                printf("遍历二叉排序树:\n");
                TraverseDSTable(dt,print);
                printf("您已经成功遍历!\n");                     
            break;
        }
    }    
    return 0;
}

s

posted @ 2019-06-27 10:36  &#127808;&#127808;&#127808;  阅读(307)  评论(0编辑  收藏  举报
🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀