二叉排序树的基本操作

不注意细节,找错找了半天。

 

 

 

 

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef struct node
{
    int d;
    node *lchild,*rchild;
}node,*BiTree;
int Search(BiTree T,int key,BiTree f,BiTree *p)
{
    if(!T)
    {
        *p=f;
        return 0;
    }
    else if(T->d==key)
    {
        *p=T;
        return 1;
    }
    else if(T->d<key)
    {
        return Search(T->rchild,key,T,p);
    }
    else
        return Search(T->lchild,key,T,p);
}
int Insert(BiTree *T,int key)
{
    BiTree q,s;
    if(!Search(*T,key,NULL,&s))
    {
        q=(BiTree)new node;  //这个node地方我错过,我误写成了BiTree 
        if(key==0)
        cout<<"99"<<endl;
        q->d=key;
        q->lchild=q->rchild=NULL;
        if(!s)
        *T=q;
        else if(key>s->d)
        s->rchild=q;
        else
        s->lchild=q;
        
    }
    
}
void ord(BiTree T)
{
    if(!T)
    return ;
    else
    {
        ord(T->lchild);
        //if(T->d==0)
        //cout<<"99"<<endl;
        cout<<T->d<<" ";
        ord(T->rchild);
    }
}
int DelBT(BiTree *T)   分为三种情况,1.叶子节点,2.单分支,3.左右孩子都有,找到左分支的最右下的节点,替换被删节点,然后调整左子树,
{
    BiTree p,w;
    if(!(*T)->lchild&&!(*T)->rchild)
    {
        *T=NULL;
    }
    else if(!(*T)->lchild)
    {
        p=*T;
        (*T)=(*T)->rchild;
        free(p);
    }
    else if(!(*T)->rchild)
    {
        p=*T;
        (*T)=(*T)->lchild;
        free(p);
    }
    else
    {
        p=(*T);
        w=p->lchild;
        while(w->rchild)
        {
            p=w;
            w=w->rchild;
        } 
        (*T)->d=w->d;
        if(p!=(*T))
           p->rchild=w->lchild;
        else
        p->lchild=w->lchild;
        return 1;
    }
}

int Del(BiTree *T,int key)
{
    if(!(*T))
    {
        cout<<"该数不在二叉排序树中!"<<endl;
        return 0;
    }
    else if(key==(*T)->d)
    {
        DelBT(T);
        return 1;
    }
    else if(key>(*T)->d)
    Del(&(*T)->rchild,key);
    else
    Del(&(*T)->lchild,key);
}
int main()
{
    BiTree T=NULL; //这点NULL害我找了半天,长记性了,指针一定要先NULL; 
    int a[10]={2,5,99,4,8,77,66,15,3,45};
    int i,j,n=10,m;
    for(i=0;i<10;i++)
    Insert(&T,a[i]);
    cout<<"中序遍历为:"<<endl;
    ord(T);
    while(n--)
    {
        cout<<"输入你要删除的元素:"<<endl;
        cin>>m;
        Del(&T,m);
        cout<<"删除后二叉排序树为:"<<endl;
        ord(T); 
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
排序也称为二搜索,它是一种特殊的二,满足以下性质: 1. 左子中的所有节点的值均小于根节点的值; 2. 右子中的所有节点的值均大于根节点的值; 3. 左子和右子也都是二排序基本操作包括插入节点、删除节点和查找节点。下面是它们的实现: 1. 插入节点: 插入节点操作用于向二排序中插入一个新节点。从根节点开始,比较插入节点的值与当前节点的值,如果小于当前节点的值,则进入左子,否则进入右子。直到找到一个空位置,将新节点插入到该位置。 示例代码如下: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None def insert_node(root, val): if root is None: return TreeNode(val) if val < root.val: root.left = insert_node(root.left, val) else: root.right = insert_node(root.right, val) return root ``` 2. 删除节点: 删除节点操作用于从二排序中删除指定节点。分为三种情况: - 被删除节点没有子节点:直接删除即可; - 被删除节点只有一个子节点:将子节点替代被删除节点的位置; - 被删除节点有两个子节点:找到被删除节点的后继节点(右子中最小的节点),将后继节点的值复制到被删除节点,然后删除后继节点。 示例代码如下: ```python def find_min(node): while node.left is not None: node = node.left return node def delete_node(root, val): if root is None: return root if val < root.val: root.left = delete_node(root.left, val) elif val > root.val: root.right = delete_node(root.right, val) else: if root.left is None: return root.right elif root.right is None: return root.left else: successor = find_min(root.right) root.val = successor.val root.right = delete_node(root.right, successor.val) return root ``` 3. 查找节点: 查找节点操作用于在二排序中查找指定值的节点。从根节点开始,比较目标值与当前节点的值,如果小于当前节点的值,则进入左子,否则进入右子。如果找到匹配的节点,则返回该节点;如果遍历完整个仍未找到匹配的节点,则返回空。 示例代码如下: ```python def search_node(root, val): if root is None or root.val == val: return root if val < root.val: return search_node(root.left, val) else: return search_node(root.right, val) ``` 以上是二排序基本操作的实现。你可以根据需要调用这些函数来操作排序

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值