搜索二叉树的基本操作

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

struct data{
    int sum;
    struct data *left ,*right;
};

void build1_tree(struct data **tree,int x){
    if(x > (*tree)->sum){
        if((*tree)->right == NULL){   //判断输入的数据与结点数据的大小
            struct data *newr = (struct data *)malloc(sizeof(struct data ));   //储存新的结点
            newr->sum = x;
            newr->left = newr->right = NULL;
            (*tree)->right = newr;
        }else{
            build1_tree(&(*tree)->right,x);
        }
    }

    if(x < (*tree)->sum){
        if((*tree)->left == NULL){
            struct data *newl = (struct data *)malloc(sizeof(struct data));
            newl->sum = x;
            newl->left = newl->right = NULL;
            (*tree)->left = newl;
        }
        else{
            build1_tree(&(*tree)->left,x);
        }
    }
}

void build_tree( struct data* *tree){  //创建二叉排序树
    int x;
    scanf("%d",&x);
    *tree = (struct data *)malloc(sizeof(struct data));
    (*tree)->right = (*tree)->left = NULL;   //根节点的指针;
    (*tree)->sum = x;  //将数据赋予根节点

    while(x != 0){
        scanf("%d",&x);   //最后的 0 也是算在里面的;
        build1_tree(&(*tree), x);
    }
}

struct data *find_tree(struct data *tree,int w){  //查找二叉排序树的结点(非递归)
    if(tree == NULL) return NULL;
    while(tree) {
        if (tree->sum == w) return tree;   //查到的出口
        if(tree->sum > w){
            tree = tree->left;
        }
        else if (tree->sum < w) {
            tree = tree->right;
        }
        else{
            break;
        }
    }
    return tree;
}

void intree(struct data **tree,int a){   //二叉排序树的插入(非递归)
    struct data *tail = *tree;
    struct data *news = (struct data *)malloc(sizeof(struct data));
    news->sum = a;
    news->left = news->right = NULL;
    if(tail == NULL){
        (tail) = news;
    }
    while((tail) != NULL) {
        if ((tail)->sum > a) {
            if ((tail)->left == NULL) {
                (tail)->left = news;
                break;
            } else {
                tail= tail->left;
            }

        }else if(tail->sum < a) {
            if (tail->right == NULL) {
                tail->right = news;
                break;
            } else {
                tail= tail->right;
            }
        }

        if(tail->sum == a){    //当树内已经存在插入的数据时  不进行操作
            break;
        }
    }
}

void print_tree(struct data *tree){    //前序遍历
    if(tree == NULL){
        return;
    }
    printf("%d ",tree->sum);
    print_tree(tree->left);
    print_tree(tree->right);
}

void midprint_tree(struct data *tree){  //后序遍历
    if(tree){
        midprint_tree(tree->left);
        midprint_tree(tree->right);
        printf("%d ",tree->sum);
    }
}

struct data * find_father(struct data *tree, int x){    // 线索二叉树寻找结点的父亲结点  中序遍历
   struct data *p = NULL;  //指向查找结点的前一个
    if(tree == NULL) return NULL;
    if(tree) {
        while (tree) {
            if (tree->sum == x) break;   //查到的出口
            if (tree->sum > x) {
                p = tree;
                tree = tree->left;
            } else if (tree->sum < x) {
                p = tree;
                tree = tree->right;
            } else {
                break;
            }
        }
    }
    return p;
}
int count_tree(struct data *tree){   //统计二叉树内的结点数
    if(tree == NULL) return 0;
    else return count_tree(tree->right) + count_tree(tree->left) + 1; //否则结点个数为左子树的结点个数+右子树的结点个数+1
}


/*
struct data * mirror_tree(struct data *tree){   //二叉树的镜像调换 (带返回值)
    if(tree == NULL) return NULL;
    if(tree){
        if(!tree->right && !tree->left) return NULL;  //左右子树都为空的情况下,直接返回空
        struct data *temp;   //临时储存左右子树的结点
        temp = tree->right;
        tree->right = tree->left;
        tree->left = temp;
        mirror_tree(tree->left);  //继续将左右子树结点下面的子树进行镜像调换
        mirror_tree(tree->right);
    }
    return tree;
}
*/


void mirror_tree(struct data* *tree) {  //不带返回值,传地址 镜像二叉树
    if ((*tree) == NULL) return;
    if (*tree) {
        if (!(*tree)->left && !(*tree)->right) return;
        struct data *temp = (*tree)->right;
        (*tree)->right = (*tree)->left;
        (*tree)->left = temp;
        mirror_tree(&(*tree)->left);
        mirror_tree(&(*tree)->right);
    }
}


struct data *FindMin( struct data*  BST ){
    if(BST == NULL) return NULL;
    else if(BST->left == NULL)  return BST;
    else return FindMin(BST->left);
}

struct data* Delete( struct data* BST, int  X ){
    struct data*  temp;
    if(!BST ) {
        printf("\n");
        printf("Not Found\n");
    }
    else{

        if(BST->sum > X){
            BST->left = Delete(BST->left,X);
        }else if(BST->sum < X){
            BST->right = Delete(BST->right,X);
        }
        else{
            if(BST->left && BST->right){
                temp = FindMin(BST->right);
                BST->sum = temp->sum;
                BST->right = Delete(BST->right,temp->sum);
            }
            else{
                temp = BST;
                if(!BST->left ){
                    BST = BST->right;
                }
                else if(!BST->right){
                    BST = BST->left;
                }
                free(temp);
            }
        }
    }
    return BST;
}




int main(){
    int w,a,b;
    struct data *tree = NULL;
    struct data *pre = NULL;   //储存被删除结点的父亲结点;
    build_tree(&tree);
    printf("前序遍历:");
    print_tree(tree);
    printf("\n");
    printf("后序遍历:");
    midprint_tree(tree);
    printf("\n请输入你要查的号码:");
    scanf("%d",&w);
    struct data *p = find_tree(tree,w);
    if(p == NULL){
        printf("查找失败!");
    }else{
        printf("%d",p->sum);
    }
    printf("\n请输入你要插入的号码:");
    scanf("%d",&a);
    intree(&tree,a);
    printf("插入后:\n");
    printf("前序遍历:");
    print_tree(tree);
    printf("\n");
    printf("后序遍历:");
    midprint_tree(tree);
    printf("\n该树的结点数量为:%d\n",count_tree(tree));
    struct data *q = find_father(tree,3);
    printf(" 结点 3 的父结点元素:%d",q->sum);
    printf("\n");
    mirror_tree(&tree);
    printf("前序遍历:");
    print_tree(tree);
    printf("\n");
    printf("中序遍历:");
    midprint_tree(tree);
    Delete(tree,5);
    printf("\n中序遍历:");
    midprint_tree(tree);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值