BST的查找、插入、删除

//
//  main.cpp
//  BinarySearchTree
//  
//  教材讲解,请参考《数据结构》第二版 严蔚敏;对应源代码,请参考《数据结构解析》高一凡,这是配套严蔚敏的一个很好的源代码教材。
//
#include <iostream>
#define N 7 /** Size of given array. */

typedef int TElemType; /** Type of Element of tree. */
typedef int KeyType;   /** Type of key. */

/** Node of tree */
typedef struct BiTNode
{
    struct BiTNode * lChild;
    struct BiTNode * rChild;
    TElemType data;
}BiTNode, *BiTree;

/** Creation of binary search tree that is linked list using a given array key. */
void createBST(BiTree& bst, const KeyType a[], const int n);

/** Traversing in infix order */
void InfixOrderTraverse(const BiTree& bt);

/** 
 * 在根指针T所指向的二叉树中进行递归查找等于key的值,
 * 若查找成功,则p指向该元素节点,并返回TRUE。
 * 若查找不成功,则p指向路径中访问的最后一个节点,并返回false。
 * f指向T的双亲,初始为NULL。
 */ 
bool SearchBST(BiTree T, KeyType key, BiTree f, BiTree& p);

/** 
 * 当BST中无查找的值时,则插入该值,并返回true,否则返回false。
 */
bool InsertBST(BiTree& T, const KeyType& key);

/**
 * 若BST中存在这样的节点,则删除该节点,并返回true。否则返回false。
 */
bool DeleteBST(BiTree& T, const KeyType& key);

/**
 * 删除该节点,并重接它的左子树或右子树。
 */
bool Delete(BiTree& p);


int main (int argc, const char * argv[])
{
    BiTree bst = NULL/*, p = NULL*/;
    KeyType a[N] = {1,4,9,6,3,8,89};
    createBST(bst, a, N);
    /*
     if(SearchBST(bst, 4, NULL, p))
     std::cout << " " << p->data << "\n";
     else
     std::cout << "没有找到.\n";
     */
    InsertBST(bst, 10);
    InfixOrderTraverse(bst);
    std::cout << "\n";
    DeleteBST(bst, 10);
    InfixOrderTraverse(bst);
    free(bst);
    return 0;
}


void createBST(BiTree& bst, const KeyType* a, const int n)
{
    BiTree nodePtr,Ptr;
    nodePtr = NULL;
    for (int i=0; i<n; i++)
    {
        Ptr = bst;
        while (Ptr)
        {//找到合适的位置
            if(Ptr->data == a[i])
                break;
            else if(a[i] > Ptr->data)
            {//进入左子树
                nodePtr = Ptr;   
                Ptr = Ptr->rChild;
            }
            else
            {//进入右子树
                nodePtr = Ptr; 
                Ptr = Ptr->lChild;
            } 
        }
        
        if (!Ptr)
        {//到达叶节点(合适位置),新建一个临时节点,并插入值.
            BiTNode* tempPtr = (BiTNode*)malloc(sizeof(BiTNode));
            tempPtr->lChild = tempPtr->rChild = NULL;
            tempPtr->data = a[i];
            
            if(nodePtr)
            {//树非空
                if(tempPtr->data < nodePtr->data)
                    nodePtr->lChild = tempPtr;
                else
                    nodePtr->rChild = tempPtr;
            }
            else //树空,即根节点为空
                bst = tempPtr;
        } 
    }
}

void InfixOrderTraverse(const BiTree& bt)
{//Traversing by infix order.That is to say, it will be order by ascending.
    if(bt)
    {
        InfixOrderTraverse(bt->lChild);
        std::cout << bt->data << " ";
        InfixOrderTraverse(bt->rChild);
    }
}

bool SearchBST(BiTree T, KeyType key, BiTree f, BiTree& p)
{
    if(!T)
    {//子树为空
        p = f; 
        return false; 
    }
    if(key == T->data)
    {//找到该值
        p = T; 
        return true;
    }
    else if(key < T->data) //比key值大,到左子树查找
        return SearchBST(T->lChild, key, T, p);
    else //比key值小,到右子树查找
        return SearchBST(T->rChild, key, T, p);
}

bool InsertBST(BiTree& T, const KeyType& key)
{
    BiTree p = NULL;
    if(!SearchBST(T,key,NULL,p))
    {//查找不成功
        BiTNode* temp = (BiTNode*)malloc(sizeof(BiTNode));
        temp->data = key;
        temp->lChild = temp->rChild = NULL;
        if(!p) //被插节点作为新的根节点
            T = temp;
        if(key < p->data) //作为左孩子
            p->lChild = temp;
        else              //作为有孩子
            p->rChild = temp;
        return true;
    }
    else
        return false; /** The key is existing. */
}

bool DeleteBST(BiTree& T, const KeyType& key)
{
    if(!T) //没找到等于key值的节点
        return false;
    else
    {
        if(key == T->data) //找到等于key值的节点
            return Delete(T);
        else if(key < T->data)
            return DeleteBST(T->lChild, key);
        else
            return DeleteBST(T->rChild, key);
    }
}

bool Delete(BiTree& p)
{
    BiTree q; 
    if(!p->rChild)
    {//Only the child left is NULL.
        q = p;
        p = p->lChild;
        free(q);
        return true;
    }
    else if(!p->lChild)
    {//Only the child right is NULL.
        q = p;
        p = p->rChild;
        free(q);
        return true;
    }
    else
    {//Both child left and child right are not NULL.
        BiTree s;
        q = p;
        s = p->lChild; //先向左走一步
        while(s->rChild)
        {//再向右走到尽头
            q = s;
            s = s->rChild;
        }
        p->data = s->data;
        if(q != p) //p的右子树的左子树不为空时
            q->rChild = s->lChild;
        else  //p的右子树的左子树为空时
            q->lChild = s->lChild;
        free(s);
        return true;
    }
    return false;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值