二叉查找树的常用函数

参考了@Indifferent-的博客,链接为C语言 二叉搜索树(建立、插入、查找和删除等基本操作)

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

typedef struct Node{
   int val;
   struct Node* left;
   struct Node* right;
}Node;
Node* createTreeNode(int val);//建立节点
Node* InsertSearchTree(Node* tree,int val);//建立查找二叉树
void InOrder(Node *root);
Node* SearchNode(Node *root,int val);//查找节点
Node* MinNode(Node *root);//最小的节点
Node* DeleteNode(Node* root,int val);//删除对应节点
int main(){
   int n;
   scanf("%d",&n);
   int x;
   Node *tree=NULL;
   for(int i=0;i<n;i++){
     scanf("%d",&x);
     tree=InsertSearchTree(tree,x);
   }
   InOrder(tree);
   printf("\n");
   int y=-1;
   Node* find=SearchNode(tree,y);
   if(find==NULL){
    printf("未查询到值为%d的节点\n",y);
   }else{
    printf("%d\n",find->val);
   }
    printf("%d\n",MinNode(tree)->val);
    tree=DeleteNode(tree,3);//头结点可能改变
    InOrder(tree);
    return 0;
}
Node* createTreeNode(int val){
    Node* ret=(Node*)malloc(sizeof(Node));
    ret->val=val;
    ret->left=ret->right=NULL;
    return ret;
}
Node* InsertSearchTree(Node* tree,int val){
   if(tree==NULL){
      tree=createTreeNode(val);
      return tree;
   }
   if(val>tree->val){
     tree->right=InsertSearchTree(tree->right,val);
     //右节点为空就在右节点位置建立val值节点,否则把原右节点返回
   }else if(val<tree->val){
      tree->left=InsertSearchTree(tree->left,val);
   }
   return tree;
}
void InOrder(Node *root){
   if(root==NULL){
      return ;
   }
   InOrder(root->left);
   printf("%d ",root->val);
   InOrder(root->right);
}
Node* SearchNode(Node *root,int val){
    if(root==NULL){
        return NULL;
    }
    if(root->val==val){
        return root;
    }

    Node *ret;//记录下面某一端返回的节点
    if(val<root->val){
       //在左端找
       ret=SearchNode(root->left,val);
    }else{
        //在右端找
       ret=SearchNode(root->right,val);
    }
    return ret;
    

}
Node* MinNode(Node *root){
    if(root==NULL){
        return NULL;
    }else if(root->left==NULL){
        //一直往左走的叶节点
        return root;
    }else{
        return MinNode(root->left);
    }
}
Node* DeleteNode(Node* root,int val){
    //使用递归形式才能真正把树结构改变,否则只改变拷贝的指针指向
    if(root==NULL){
        return NULL;
    }else if(val<root->val){
        root->left=DeleteNode(root->left,val);//若左节点未被删除返回原节点
    }else if(val>root->val){
        root->right=DeleteNode(root->right,val);
    }else{
        //查找到节点
        if(root->left==NULL&&root->right==NULL){
            free(root);
            root=NULL;
        }else if(root->left==NULL){
            Node *tem=root;
            root=root->right;
            free(tem);
        }else if(root->right==NULL){
            Node *tem=root;
            root=root->left;
            free(tem);
        }else{
            //用右支最小的节点覆盖删除节点,对应节点删除
            Node *tem=MinNode(root->right);
            root->val=tem->val;
            root->right=DeleteNode(root->right,tem->val);
            //进行递归性删除
        }
        
    }
    return root;
}
// Node* DeleteNode(Node* root,int val){
//     Node *root=SearchNode(root,val);
//     if(root->left==NULL&&root->right==NULL){
//         free(root);
//         root=NULL;
//     }else if(root->left==NULL){
//         Node *tem=root;
//         root=root->right;
//         free(tem);
//     }else if(root->right==NULL){
//         Node *tem=root;
//         root=root->left;
//         free(tem);
//     }else{
//         //用右支最小的节点代替删除节点
//         Node *tem=root;
//         root=MinNode(root->right);
//         free(tem);
//     }
//     return root;
// }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值