二叉搜素树 二叉排序树 插入 删除 中序输出

本文详细介绍了二叉查找树的基本概念及其操作实现,包括插入、删除、查找最小元素及中序遍历等核心功能,并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
函数:二叉搜素树  二叉排序树
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 
它的左、右子树也分别为二叉排序树
node.left<node.key<node.right


注意:
node->p 的处理

时间:15.7.21
Jason Zhou  
热爱你所写下的程序,他是你的伙伴,而不是工具.
*/


#include<iostream>
using namespace std;

typedef struct node
{
    int key;
    node* left;
    node* right;
    node* p;//parent node
};

//查找最小元素,从该节点不断变量左孩子
node* tree_min(node * x)
{
    while (NULL!=x->left)
    {
        x=x->left;
    }
    return x;
}


//插入元素
int tree_insert(node* & root,int  k)
{
    //创建要插入节点
    node * z=new node;
    z->key=k;
    z->left=NULL;
    z->right=NULL;
    z->p=NULL;

    if (NULL==root)//如果树为空
    {
        root=z;
        return 0;
    }

    node * y;
    node * x=root;
    while(NULL!=x)
    {
        y=x;//迭代量,作为插入节点的父节点
        if (k<x->key)
            x=x->left;
        else
            x=x->right;
    }

    //节点z插入到y下方
    if (k<y->key)
        y->left=z;
    else
        y->right=z;
    //特别注意,处理parents
    z->p=y;

    return 0;
}


//删除元素
/*
分为三种情况:
1)仅有左子树或又子树,直接替换.
含有左右孩子.
2)后继是节点的右孩子,后继替换节点
3)后继离节点较远.
比较复杂替换
*/

//删除的子函数,使用v,替换u.
//允许v为null.注意没有处理v的left和right信息.需要调用者处理.
int trans_plant(node * &root,node * u,node * v)
{
    if (NULL==u->p)//根节点
    {
        root=u;
    }
    else if (u==(u->p)->left)
    {
        (u->p)->left=v;
    }else
    {
        (u->p)->right=v;
    }

    if (NULL!=v)//处理parents信息
    {
        v->p=u->p;
    }

    return 0;
}

//删除节点
int tree_delete(node *&root,node * z)
{
    if (NULL==z->left)
    {
        trans_plant(root,z,z->right);
    }
    else if (NULL==z->right)
    {
        trans_plant(root,z,z->left);
    }else
    {
        node *y=tree_min(z->right);
        cout<<"后继: "<<y->key<<endl;

        if (y->p!=z)
        {
            trans_plant(root,y,y->right);
            y->right=z->right;
            (y->right)->p=y;
        }
        trans_plant(root,z,y);
        y->left=z->left;
        (y->left)->p=y;

    }


    return 0;

}
//中序遍历
int inorder_tree_walk(node * x)
{
    if (NULL!=x)
    {
        inorder_tree_walk(x->left);
        cout<<" "<<x->key;
        inorder_tree_walk(x->right);
    }
    return 0;
}




//删除搜索树
int clean(node * root)
{
    if (root!=NULL)
    {
        clean(root->left);
        clean(root->right);
        delete(root);
    }
    return 0;
}


int main()
{
    int arr[]={15,6,18,3,7,2,4,13,9,17,20};
    int len=sizeof(arr)/sizeof(arr[0]);

    cout<<"原始数据"<<endl;
    for (int i=0;i<len;i++)
    {
        cout<<arr[i]<<" ";
    }
    cout<<endl;

    node * root=NULL;//根节点

    //插入数据
    for (int j=0;j<len;j++)
    {
        tree_insert(root,arr[j]);
    }
    tree_delete(root,root->left);

    inorder_tree_walk(root);
    cout<<endl;

    clean(root);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值