ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构 04-树7 二叉搜索树的操作集 (30 分)

2021-05-16 03:03:09  阅读:225  来源: 互联网

标签:结点 Right 04 BST 30 二叉 NULL BinTree Left


本题要求实现给定二叉搜索树的5种常用操作。

函数接口定义:

BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
 

其中BinTree结构定义如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};
 
  • 函数InsertX插入二叉搜索树BST并返回结果树的根结点指针;
  • 函数DeleteX从二叉搜索树BST中删除,并返回结果树的根结点指针;如果X不在树中,则打印一行Not Found并返回原树的根结点指针;
  • 函数Find在二叉搜索树BST中找到X,返回该结点的指针;如果找不到则返回空指针;
  • 函数FindMin返回二叉搜索树BST中最小元结点的指针;
  • 函数FindMax返回二叉搜索树BST中最大元结点的指针。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

void PreorderTraversal( BinTree BT ); /* 先序遍历,由裁判实现,细节不表 */
void InorderTraversal( BinTree BT );  /* 中序遍历,由裁判实现,细节不表 */

BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );

int main()
{
    BinTree BST, MinP, MaxP, Tmp;
    ElementType X;
    int N, i;

    BST = NULL;
    scanf("%d", &N);
    for ( i=0; i<N; i++ ) {
        scanf("%d", &X);
        BST = Insert(BST, X);
    }
    printf("Preorder:"); PreorderTraversal(BST); printf("\n");
    MinP = FindMin(BST);
    MaxP = FindMax(BST);
    scanf("%d", &N);
    for( i=0; i<N; i++ ) {
        scanf("%d", &X);
        Tmp = Find(BST, X);
        if (Tmp == NULL) printf("%d is not found\n", X);
        else {
            printf("%d is found\n", Tmp->Data);
            if (Tmp==MinP) printf("%d is the smallest key\n", Tmp->Data);
            if (Tmp==MaxP) printf("%d is the largest key\n", Tmp->Data);
        }
    }
    scanf("%d", &N);
    for( i=0; i<N; i++ ) {
        scanf("%d", &X);
        BST = Delete(BST, X);
    }
    printf("Inorder:"); InorderTraversal(BST); printf("\n");

    return 0;
}
/* 你的代码将被嵌在这里 */
 

输入样例:

10
5 8 6 2 4 1 0 10 9 7
5
6 3 10 0 5
5
5 7 0 10 3
 

输出样例:

Preorder: 5 2 1 0 4 8 6 7 10 9
6 is found
3 is not found
10 is found
10 is the largest key
0 is found
0 is the smallest key
5 is found
Not Found
Inorder: 1 2 4 6 8 9

 

 

BinTree Insert( BinTree BST, ElementType X ){
    BinTree p=BST;
    BinTree parent=NULL;
    BinTree newnode=(BinTree)malloc(sizeof(struct TNode));
    newnode->Data=X;
    newnode->Left=NULL;
    newnode->Right=NULL;
    while(p!=NULL){//寻找合适位置插入
        parent=p;
        if(X<p->Data){
            p=p->Left;
        }else{
            p=p->Right;
        }
    }
    if(parent==NULL){
        BST=newnode;
    }else if(X<parent->Data){
        parent->Left=newnode;
    }else{
        parent->Right=newnode;
    }
    return BST;
}

BinTree Delete( BinTree BST, ElementType X ){
    BinTree p=BST,parent=NULL;//如果父节点为NULL说明是根结点
    int flag=1;
    while(p!=NULL){
        if(X<p->Data){//小于从左子树找
            parent=p;//标记父节点
            p=p->Left;
        }else if(X>p->Data){//大于从右子树找
            parent=p;
            p=p->Right;
        }else{//找到了要删除的结点
            flag=0;//标记找到了结点
            if(p->Left==NULL&&p->Right==NULL){//首先处理叶子结点
                if(parent==NULL){//要删除的结点是 只有一个结点的根结点 直接返回空树
                    BST=NULL;//根节点置为空
                    break;
                }else{//非根的叶结点
                    //删除的结点小于父结点 则是左子结点 把父结点的左子结点置为NULL 反之是右子结点
                    (p->Data<parent->Data)?(parent->Left=NULL):(parent->Right=NULL);
                    break;
                }
            }else if(p->Left==NULL&&p->Right!=NULL){//要删除的结点只有 右子树
                if(parent==NULL){//该结点是根结点 没有父结点
                    BST=BST->Right;
                    break;
                }else{//非根结点
                    //删除的结点小于父结点是左子结点 把父结点的左子结点指向删除结点的右子树
                    //反之是父结点的右子结点指向删除结点的右子树
                    (p->Data<parent->Data)?(parent->Left=p->Right):(parent->Right=p->Right);
                    break;
                }
            }else if(p->Left!=NULL&&p->Right==NULL){//要删除的结点只有左子树
                if(parent==NULL){//该结点是根结点 没有父结点 没有右子树
                    BST=BST->Left;
                    break;
                }else {
                     //删除的结点小于父结点是左子结点 把父结点的左子结点指向删除结点的左子树
                    //反之是父结点的右子结点指向删除结点的左子树
                    (p->Data<parent->Data)?(parent->Left=p->Left):(parent->Right=p->Left);
                    break;
                   //
                }
            }else{//要删除的结点有左子树同时有右子树
                    BinTree tempP=p;//需要一个新的结点 暂存p结点
                    //这里寻找p的前驱作为替换结点 也就是左子树的最大结点
                    p=p->Left;//从左子树开始找左子树的最大结点
                    while(p->Right!=NULL){//保存父结点的同时 一直找到左子树的最大值
                        parent=p;
                        p=p->Right;
                    }
                    //父结点的右子树指向 最大值的的左子树
                    parent->Right=p->Left;
                    //然后将最大值结点的左右子树 指向 删除结点的左右子树
                    tempP->Data=p->Data;
                    break;
            }
        }
    }
    if(flag){
        printf("Not Found\n");
    }
    return BST;
}

Position Find( BinTree BST, ElementType X ){
    BinTree p=BST;
    while(p!=NULL){
        if(p->Data==X){
            break;
        }else if(X<p->Data){
            p=p->Left;
        }else{
            p=p->Right;
        }
    }
    return p;
}
Position FindMin( BinTree BST ){
    BinTree p=BST;
    while(p!=NULL){
        if(p->Left==NULL){//直到最后一个左子树为空的结点就是最小结点
            break;
        }else{
            p=p->Left;
        }
    }
    return p;
}
Position FindMax( BinTree BST ){
    BinTree p=BST;
    while(p!=NULL){
        if(p->Right==NULL){//直到最后一个右子树为空的结点就是最大结点
            break;
        }else{
            p=p->Right;
        }
    }
    return p;
}

 

标签:结点,Right,04,BST,30,二叉,NULL,BinTree,Left
来源: https://www.cnblogs.com/ichiha/p/14773064.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有