二叉搜索树的基本操作

二叉搜索树实现—> 循环

#pragma once
#include <assert.h>
#include <stdio.h>
#include <malloc.h>
typedef int DataType;
typedef struct BSTreeNode
{
    DataType _data;
    struct BSTreeNode* _pLeft;
    struct BSTreeNode* _pRight;
}BSTNode,*pBSTNode;

//二叉搜索树的创建

void bintree_create(pBSTNode* tRoot,DataType array[])
{
    int index=0;
    _bintree_create(tRoot,array,&index);
}
void _bintree_create(pBSTNode* tRoot,DataType array[],int* index)
{
    assert(tRoot);
    if('*' != array[*index] && '#'!=array[*index])
    {
        //根节点的创建
        *tRoot=bintreenode_create(array[*index]);
        //左子树的创建
        ++(*index);
        _bintree_create(&(*tRoot)->_pLeft,array,index);
        //右子树的创建
        ++(*index);
        _bintree_create(&(*tRoot)->_pRight,array,index);
    }
}
//节点的创建
pBSTNode bintreenode_create(DataType data)
{
    pBSTNode pNewNode=NULL;
    pNewNode=(pBSTNode)malloc(sizeof(BSTNode));
    if(NULL == pNewNode)
    {
        assert(pNewNode);
        return NULL;
    }
    pNewNode->_data=data;
    pNewNode->_pLeft=NULL;
    pNewNode->_pRight=NULL;
    return pNewNode;
}

//节点的查找

pBSTNode Is_bstNode(pBSTNode tRoot,DataType data)
{
    if(NULL==tRoot)
        return NULL;
    if(data==tRoot->_data)
        return tRoot;
    else if(data<tRoot->_data)
        return Is_bstNode(tRoot->_pLeft,data);
    else if(data>tRoot->_data)
        return Is_bstNode(tRoot->_pRight,data);
    return NULL;
}

//节点的插入

void  insert_bintreeNode(pBSTNode* tRoot,DataType data)
{

    pBSTNode pCur=*tRoot,parent=NULL;
    //1、树为空,则直接插入?
    if(NULL==pCur)
    {
        pCur=bintreenode_create(data); 
        return;
    }
    //2、树不空,按二叉搜索树性质查找插入位置,插入新节点?
    while (pCur)
    {
         if(data>pCur->_data)
         {
             parent=pCur;
             pCur=pCur->_pRight;
         }
         else if(data<pCur->_data)
         {
             parent=pCur;
             pCur=pCur->_pLeft;
         }
         else
             return;
    }
    if(data>parent->_data)
        parent->_pRight=bintreenode_create(data);
    else
        parent->_pLeft=bintreenode_create(data);
}

//节点的删除

void delete_bstNode(pBSTNode* tRoot,DataType data)
{
     //找待删除节点位置
     pBSTNode pParent=*tRoot,pCur=*tRoot;
     if(NULL==pCur)
         return;
     while (pCur)
     {
         if(data==pCur->_data)
            break;
         else if(data>pCur->_data)
         {
             pParent=pCur;
             pCur=pCur->_pRight;
         }
         else
         {
             pParent=pCur;
             pCur=pCur->_pLeft;
         }
     }
     //要删除的结点右孩子为空(包括无左右孩子)
     if(NULL==pCur->_pRight)
     {
         //pCur是根节点
         if((*tRoot)==pCur)      
             *tRoot=pCur->_pLeft;
         else
         {
             //待删节点是双亲节点的左孩子
             if(pParent->_pLeft==pCur)
                 pParent->_pLeft=pCur->_pLeft;
             else
                 pParent->_pRight=pCur->_pLeft;
         }
     }
     //要删除的结点只有右孩子结点
     else if(NULL==pCur->_pLeft)
     {
         //pCur是根节点
         if((*tRoot)==pCur)      
             *tRoot=pCur->_pRight;
         else
         {
             //待删节点是双亲节点的左孩子
             if(pParent->_pLeft==pCur)
                 pParent->_pLeft=pCur->_pRight;
             else
                 pParent->_pRight=pCur->_pRight;
         }
     }
     //要删除的结点左右孩子结点均存在
     else
     {
         pBSTNode pDel=pCur->_pRight;
         pParent=pCur;
         //在双亲节点的左子树找最大的节点或者在右子树中找最小的节点
         while (pDel->_pLeft)
         {
             pParent=pDel;
             pDel=pDel->_pLeft;
         }
         pCur->_data=pDel->_data;
         //替换节点的右子树存在
         if(pDel->_pRight)
            pParent->_pRight=pDel->_pRight;   
         pCur=pDel;
     }
     free(pCur);
     pCur=NULL;
}

递归实现二叉搜索树中查找、插入和删除方法

//二叉搜索树的创建

void bintree_create(pBSTNode* tRoot,DataType array[])
{
    int index=0;
    _bintree_create(tRoot,array,&index);
}
void _bintree_create(pBSTNode* tRoot,DataType array[],int* index)
{
    assert(tRoot);
    if('*' != array[*index] && '#'!=array[*index])
    {
        //根节点的创建
        *tRoot=bintreenode_create(array[*index]);
        //左子树的创建
        ++(*index);
        _bintree_create(&(*tRoot)->_pLeft,array,index);
        //右子树的创建
        ++(*index);
        _bintree_create(&(*tRoot)->_pRight,array,index);
    }
}
//节点的创建
pBSTNode bintreenode_create(DataType data)
{
    pBSTNode pNewNode=NULL;
    pNewNode=(pBSTNode)malloc(sizeof(BSTNode));
    if(NULL == pNewNode)
    {
        assert(pNewNode);
        return NULL;
    }
    pNewNode->_data=data;
    pNewNode->_pLeft=NULL;
    pNewNode->_pRight=NULL;
    return pNewNode;
}

//节点的查找

pBSTNode Is_bstNode(pBSTNode tRoot,DataType data)
{
    if(NULL==tRoot)
        return NULL;
    if(data==tRoot->_data)
        return tRoot;
    else if(data<tRoot->_data)
        return Is_bstNode(tRoot->_pLeft,data);
    else if(data>tRoot->_data)
        return Is_bstNode(tRoot->_pRight,data);
    return NULL;
}

//节点的插入

void  insert_bintreeNode(pBSTNode* tRoot,DataType data)
{
    //1、树为空,则直接插入?
    if(NULL==(*tRoot))
    {
        *tRoot=bintreenode_create(data); 
        return;
    }
    //2、树不空,按二叉搜索树性质查找插入位置,插入新节点?
    if(data > (*tRoot)->_data)
        insert_bintreeNode(&((*tRoot)->_pRight),data);
    else
        insert_bintreeNode(&((*tRoot)->_pLeft),data);
}

//节点的删除

void delete_bstNode(pBSTNode* tRoot,DataType data)
{
    //找待删除节点位置
    if(NULL==(*tRoot))
        return;
    if(data > (*tRoot)->_data)
        delete_bstNode(&(*tRoot)->_pRight,data);
    else if(data < (*tRoot)->_data)
        delete_bstNode(&(*tRoot)->_pLeft,data);
    else
    {
        pBSTNode pDel=*tRoot;
        //要删除的结点右孩子为空(包括无左右孩子)
        if(NULL==pDel->_pRight)
        {
            *tRoot=pDel->_pLeft;
            free(pDel);
        }
        //要删除的结点只有右孩子结点
        else if(NULL==pDel->_pLeft)
        {
            *tRoot=pDel->_pRight;
            free(pDel);
        }
        //要删除的结点左右孩子结点均存在
        else
        {
            pDel=pDel->_pRight;
            while (pDel->_pLeft)
                pDel=pDel->_pLeft;
            (*tRoot)->_data=pDel->_data;
            //现在转变成删替代节点pDel
            delete_bstNode(&(*tRoot)->_pRight,pDel->_data);
        }
    }
}

//中序遍历

void MidOrder(pBSTNode tRoot)
{
    if(NULL==tRoot)
        return;
    MidOrder(tRoot->_pLeft);
    printf("%d ",tRoot->_data);
    MidOrder(tRoot->_pRight);
}

//销毁二叉搜索树(后序)

void DestroyBSTree(pBSTNode* tRoot)
{
    if(NULL==(*tRoot))
        return;
    DestroyBSTree(&(*tRoot)->_pLeft);
    DestroyBSTree(&(*tRoot)->_pRight);
    free(*tRoot);
}

整理二叉搜索树中的应用
1. 判断一个单词是否拼写正确
2. 请模拟实现一个简单的字典

typedef struct pair
{
    char* _word;
    char* _Chinese;
}pair;
typedef pair* DataType;
创建一个二叉搜索树,数据域就保存DataType;要想更准确的查词,就要保证这个二叉树里已经存了足够多的“pair”;在查词时,将word与pair->_word比较.
  1. log文件中有许多异常重复的IP地址,请统计出每个异常IP出现了多少
    次?
typedef struct IP
{
    int _ip;
    int _count;  //用来记录当前ip出现的次数
} 

将每个ip向二叉树里插入,当遇到相同的ip时,就将对应ip的count加1;当插入完成时,就可以知道每个ip的重复次数。

分析二叉搜索树性能
插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的
性能。
对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平
均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数
越多
但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同
结构的二叉搜索树
最优情况下,二叉搜索树为完全二叉树,其平均比较次数为:
最差情况下,二叉搜索树退化为单支树,其平均比较次数为:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值