二叉搜索树 及 c++代码实现

本文算法参考《算法导论》chp12

未解决问题:搜索时越界问题完美解决。(解决方案1.可以是在每个叶子结点都设置标志位,2.在每个结点后认为加一个节点,这样开销会更大些)

   本文提供了一种解决方案,不过在main函数进行返回值判定,代码封装性并不是特别好

构造二叉树、插入、删除、搜索、  查找最大值、最小值、前驱、后继的各种实现

具体代码如下:

#include<iostream>
#include<cstdlib>
using namespace std;

typedef int keyType;
typedef struct Node
{
    keyType val;
    Node* lChild;
    Node* rChild;
    Node* parent;
}Node,*RootNode;

void viewTree(RootNode root)    //中续遍历全树
{
    if(root!=NULL)
    {
        viewTree(root->lChild);
        cout<<root->val<<" ";
        viewTree(root->rChild);
    }
}

//Node* searchTree(const RootNode root,const keyType key)    //使用递归的方法,下面的一种效率会更高一点
//{
//    if(root==NULL||key==root->val)
//        return root;
//    if(key<root->val)
//        return searchTree(root->lChild,key);
//    else
//        return searchTree(root->rChild,key);
//}

Node* searchTree(RootNode root,const keyType key)             //增加了越界保护
{
    Node *temp=root;
    while(temp!=NULL&&key!=temp->val)
        (key<temp->val)? temp=temp->lChild :temp=temp->rChild;
    if(temp==NULL)
        return NULL;
    return temp;
}



Node* minTree(RootNode root)             //返回最小值
{
    while(root->lChild!=NULL)
        root=root->lChild;
    return root;
}

Node* maxTree(RootNode root)             //返回最大值
{
    while(root->rChild!=NULL)
        root=root->rChild;
    return root;
}

Node* successorTree(RootNode root,const keyType key)    //寻找后继结点
{
    Node* p=searchTree(root,key);
    if(p->rChild!=NULL)
        return minTree(p->rChild);
    
    Node* parTemp=p->parent;
    while(parTemp!=NULL&&p==parTemp->rChild)
    {
        p=parTemp;
        parTemp=parTemp->parent;
    }
    return parTemp;
}

Node* forwardTree(RootNode root,const keyType key)    //寻找前继节点
{
    Node *p=searchTree(root,key);
    if(p->lChild!=NULL)
        return maxTree(p->lChild);
    
    Node* parTemp=p->parent;
    while(parTemp!=NULL&&p==parTemp->lChild)
    {
        p=parTemp;
        parTemp=parTemp->parent;
    }
    return parTemp;
}

void insertTree(RootNode *root,keyType key)         //插入新节点
{
    Node *p=(Node*)malloc(sizeof(Node));
    Node *temp=*root;
    p->val=key;
    p->lChild=p->rChild=p->parent=0;
    
    Node *y=NULL;
    while(temp!=NULL)
    {
        y=temp;
        if(key<temp->val)
            temp=temp->lChild;
        else 
            temp=temp->rChild;
    }
    
    p->parent=y;
    if(y==NULL)
        *root=p;
    else if(key<y->val)
            y->lChild=p;            
    else
        y->rChild=p;
}

void deleteTree(RootNode *root,keyType key)        //删除节点
{
    Node *y,*x;
    Node *p=searchTree(*root,key);
    if(p->lChild==NULL|p->rChild==NULL)
        y=p;
    else
        y=successorTree(*root,key);
    
    if(y->lChild!=NULL) 
        x=y->lChild;
    else
        x=y->rChild;
    
    if(x!=NULL)
        x->parent=y->parent;
    
    if(y->parent==NULL)
        *root=x;
    else if(y==y->parent->lChild)
            y->parent->lChild=x;
    else
        y->parent->rChild=x;
    
    if(y!=p)
        p->val=y->val;
    delete y;

}

void createTree(RootNode *root,keyType *arr,int length)              //创建二叉搜索树
{
    for(int i=0;i<length;i++)
        insertTree(root,arr[i]);
}

int main()
{
    keyType arr[10]={21,3,2,12,34,43,23,65,78,56};
    RootNode root=NULL;
    //insertTree(&root,1);
    //insertTree(&root,4);
    //insertTree(&root,2);
    //insertTree(&root,5);
    createTree(&root,arr,10);
    viewTree(root);
    cout<<endl;
    insertTree(&root,100);
    viewTree(root);
    cout<<endl;
    Node *p=searchTree(root,10);
    if(p==NULL)
        cout<<"the number is not exist"<<endl;
    else
        cout<<p->val<<endl;
    p=searchTree(root,12);
    if(p==NULL)
        cout<<"the number is not exist"<<endl;
    else
        cout<<p->val<<endl;
    cout<<minTree(root)->val<<endl;
    cout<<maxTree(root)->val<<endl;
    cout<<successorTree(root,3)->val<<endl;
    cout<<forwardTree(root,3)->val<<endl;

    deleteTree(&root,2);
    viewTree(root);
    cout<<endl;
    return 0;

}

输入结果如下所示




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值