二叉排序树的时间复杂度

二叉排序树又称二叉查找树,它或是一棵空的二叉树,或是具有下列性质的二叉树:

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值
  • 若它的右子树不空,则右子树上所有节点的值均大于根节点的值
  • 它的左右子树也都是二叉排序树
由上述定义可知, 中虚遍历二叉排序树可以得到一个按关键码有序的序列。

  1. template<class T>  
  2. struct BiNode  
  3. {  
  4.     T data;  
  5.     BiNode<T>*lchild,rchild;  
  6. }  
  7. class BiSortTree  
  8. {  
  9.  public:  
  10.     BiSortTree(int a[],int n);  
  11.     ~BiSortTree();  
  12.     void InsertBST(BiNode<int>*root,BiNode<int>*s);  
  13.     void DeleteBST(BiNode<int>*p,BiNode<int>*f);  
  14.     BiNode<int>*SearchBST(BiNode<int>*root,int k);  
  15.  private:  
  16.     BiNode<int>*root;  
  17. }  
  18.   
  19. void BiSortTree::InsertBST(BiNode<int>*root,BiNode<int>*s)  
  20. {  
  21.     if(root==NULL)  
  22.         root=s;  
  23.     else if(s->data<root->data)  
  24.         InsertBST(root->lchild,s);  
  25.     else  
  26.         InsertBST(root->rchild,s);  
  27. }     
  28.   
  29. BiSortTree::BiSortTree(int r[],int n)  
  30. {  
  31.     for(int i=0;i<n;i++)  
  32.     {  
  33.         BiNode<int>s=new BiNode<int>;  
  34.         s->data=r[i];  
  35.         s->lchild=s->rchild=NULL;  
  36.         InsertBST(root,s);  
  37.     }  
  38. }  
  39. //在二叉排序树中删除一个节点f的左孩子节点p的算法:  
  40. //1.若节点p是叶子,则直接删除节点p  
  41. //2.若节点p只有左子树,则需重接p的左子树;若节点p只有右子树,则需重接p的右子树  
  42. //3.若节点p的左右子树都不为空,则  
  43. //  3.1查找节点p的右子树上的最左下节点s以及节点s的双亲节点par  
  44. //  3.2将节点s的数据域替换到被删除节点p的数据域  
  45. //  3.3若节点p的右孩子无左子树,则将s的右子树接到par的右子树上;否则将s的右子树接到节点par的左子树上  
  46. //  3.4删除节点s;  
  47. void BiSortTree::DeleteBST(BiNode<int>*p,BiNode<int>*f)  
  48. {  
  49.     if((p->lchild==NULL)&&(p->rchild)==NULL)  
  50.     {  
  51.         f->lchild=NULL;  
  52.         delete p;  
  53.     }  
  54.     else if(p->rchild==NULL)  
  55.     {  
  56.         f->lchild=p->lchild;  
  57.         delete p;  
  58.     }  
  59.     else if(p->lchild==NULL)  
  60.     {  
  61.         f->lchild=p->rchild;  
  62.         delete p;  
  63.     }  
  64.     else{  
  65.         BiNode<int>*par=p;  
  66.         BiNode<int>*s=p->rchild;  
  67.         while(s->lchild!=NULL)  
  68.         {  
  69.             par=s;  
  70.             s=s->lchild  
  71.         }  
  72.         p->data=s->data;  
  73.         if(par==p)  
  74.             par->rchild=s->rchild;  
  75.         else  
  76.             par->lchild=s->rchild;  
  77.         delete s;  
  78.           
  79.     }  
  80.       
  81. }  
  82. BiNode<int>*BiSortTree::SearchBST(BiNode<int>*root,int k)  
  83. {  
  84.     if(root==NULL)  
  85.         return NULL;  
  86.     else if(root->data==k)  
  87.         return root;  
  88.     else if(root->date>k)  
  89.         return SearchBST(root->lchild,k);  
  90.     else if(root->data<k)  
  91.         return SearchBST(root->rchild,k);  
  92. }  
template<class T>
struct BiNode
{
    T data;
    BiNode<T>*lchild,rchild;
}
class BiSortTree
{
 public:
    BiSortTree(int a[],int n);
    ~BiSortTree();
    void InsertBST(BiNode<int>*root,BiNode<int>*s);
    void DeleteBST(BiNode<int>*p,BiNode<int>*f);
    BiNode<int>*SearchBST(BiNode<int>*root,int k);
 private:
    BiNode<int>*root;
}

void BiSortTree::InsertBST(BiNode<int>*root,BiNode<int>*s)
{
    if(root==NULL)
        root=s;
    else if(s->data<root->data)
        InsertBST(root->lchild,s);
    else
        InsertBST(root->rchild,s);
}   

BiSortTree::BiSortTree(int r[],int n)
{
    for(int i=0;i<n;i++)
    {
        BiNode<int>s=new BiNode<int>;
        s->data=r[i];
        s->lchild=s->rchild=NULL;
        InsertBST(root,s);
    }
}
//在二叉排序树中删除一个节点f的左孩子节点p的算法:
//1.若节点p是叶子,则直接删除节点p
//2.若节点p只有左子树,则需重接p的左子树;若节点p只有右子树,则需重接p的右子树
//3.若节点p的左右子树都不为空,则
//  3.1查找节点p的右子树上的最左下节点s以及节点s的双亲节点par
//  3.2将节点s的数据域替换到被删除节点p的数据域
//  3.3若节点p的右孩子无左子树,则将s的右子树接到par的右子树上;否则将s的右子树接到节点par的左子树上
//  3.4删除节点s;
void BiSortTree::DeleteBST(BiNode<int>*p,BiNode<int>*f)
{
    if((p->lchild==NULL)&&(p->rchild)==NULL)
    {
        f->lchild=NULL;
        delete p;
    }
    else if(p->rchild==NULL)
    {
        f->lchild=p->lchild;
        delete p;
    }
    else if(p->lchild==NULL)
    {
        f->lchild=p->rchild;
        delete p;
    }
    else{
        BiNode<int>*par=p;
        BiNode<int>*s=p->rchild;
        while(s->lchild!=NULL)
        {
            par=s;
            s=s->lchild
        }
        p->data=s->data;
        if(par==p)
            par->rchild=s->rchild;
        else
            par->lchild=s->rchild;
        delete s;

    }

}
BiNode<int>*BiSortTree::SearchBST(BiNode<int>*root,int k)
{
    if(root==NULL)
        return NULL;
    else if(root->data==k)
        return root;
    else if(root->date>k)
        return SearchBST(root->lchild,k);
    else if(root->data<k)
        return SearchBST(root->rchild,k);
}

给定值的比较次数等于给定值节点在二叉排序树中的层数。如果二叉排序树是平衡的,则n个节点的二叉排序树的高度为Log 2n+1,其查找效率为O(Log 2n),近似于折半查找。如果二叉排序树完全不平衡,则其深度可达到n,查找效率为O(n),退化为顺序查找。一般的,二叉排序树的查找性能在O(Log 2n)到O(n)之间。因此,为了获得较好的查找性能,就要构造一棵平衡的二叉排序树。

二叉排序树又称二叉查找树,它或是一棵空的二叉树,或是具有下列性质的二叉树:

  • 若它的左子树不空,则左子树上所有节点的值均小于根节点的值
  • 若它的右子树不空,则右子树上所有节点的值均大于根节点的值
  • 它的左右子树也都是二叉排序树
由上述定义可知, 中虚遍历二叉排序树可以得到一个按关键码有序的序列。

  1. template<class T>  
  2. struct BiNode  
  3. {  
  4.     T data;  
  5.     BiNode<T>*lchild,rchild;  
  6. }  
  7. class BiSortTree  
  8. {  
  9.  public:  
  10.     BiSortTree(int a[],int n);  
  11.     ~BiSortTree();  
  12.     void InsertBST(BiNode<int>*root,BiNode<int>*s);  
  13.     void DeleteBST(BiNode<int>*p,BiNode<int>*f);  
  14.     BiNode<int>*SearchBST(BiNode<int>*root,int k);  
  15.  private:  
  16.     BiNode<int>*root;  
  17. }  
  18.   
  19. void BiSortTree::InsertBST(BiNode<int>*root,BiNode<int>*s)  
  20. {  
  21.     if(root==NULL)  
  22.         root=s;  
  23.     else if(s->data<root->data)  
  24.         InsertBST(root->lchild,s);  
  25.     else  
  26.         InsertBST(root->rchild,s);  
  27. }     
  28.   
  29. BiSortTree::BiSortTree(int r[],int n)  
  30. {  
  31.     for(int i=0;i<n;i++)  
  32.     {  
  33.         BiNode<int>s=new BiNode<int>;  
  34.         s->data=r[i];  
  35.         s->lchild=s->rchild=NULL;  
  36.         InsertBST(root,s);  
  37.     }  
  38. }  
  39. //在二叉排序树中删除一个节点f的左孩子节点p的算法:  
  40. //1.若节点p是叶子,则直接删除节点p  
  41. //2.若节点p只有左子树,则需重接p的左子树;若节点p只有右子树,则需重接p的右子树  
  42. //3.若节点p的左右子树都不为空,则  
  43. //  3.1查找节点p的右子树上的最左下节点s以及节点s的双亲节点par  
  44. //  3.2将节点s的数据域替换到被删除节点p的数据域  
  45. //  3.3若节点p的右孩子无左子树,则将s的右子树接到par的右子树上;否则将s的右子树接到节点par的左子树上  
  46. //  3.4删除节点s;  
  47. void BiSortTree::DeleteBST(BiNode<int>*p,BiNode<int>*f)  
  48. {  
  49.     if((p->lchild==NULL)&&(p->rchild)==NULL)  
  50.     {  
  51.         f->lchild=NULL;  
  52.         delete p;  
  53.     }  
  54.     else if(p->rchild==NULL)  
  55.     {  
  56.         f->lchild=p->lchild;  
  57.         delete p;  
  58.     }  
  59.     else if(p->lchild==NULL)  
  60.     {  
  61.         f->lchild=p->rchild;  
  62.         delete p;  
  63.     }  
  64.     else{  
  65.         BiNode<int>*par=p;  
  66.         BiNode<int>*s=p->rchild;  
  67.         while(s->lchild!=NULL)  
  68.         {  
  69.             par=s;  
  70.             s=s->lchild  
  71.         }  
  72.         p->data=s->data;  
  73.         if(par==p)  
  74.             par->rchild=s->rchild;  
  75.         else  
  76.             par->lchild=s->rchild;  
  77.         delete s;  
  78.           
  79.     }  
  80.       
  81. }  
  82. BiNode<int>*BiSortTree::SearchBST(BiNode<int>*root,int k)  
  83. {  
  84.     if(root==NULL)  
  85.         return NULL;  
  86.     else if(root->data==k)  
  87.         return root;  
  88.     else if(root->date>k)  
  89.         return SearchBST(root->lchild,k);  
  90.     else if(root->data<k)  
  91.         return SearchBST(root->rchild,k);  
  92. }  
template<class T>
struct BiNode
{
    T data;
    BiNode<T>*lchild,rchild;
}
class BiSortTree
{
 public:
    BiSortTree(int a[],int n);
    ~BiSortTree();
    void InsertBST(BiNode<int>*root,BiNode<int>*s);
    void DeleteBST(BiNode<int>*p,BiNode<int>*f);
    BiNode<int>*SearchBST(BiNode<int>*root,int k);
 private:
    BiNode<int>*root;
}

void BiSortTree::InsertBST(BiNode<int>*root,BiNode<int>*s)
{
    if(root==NULL)
        root=s;
    else if(s->data<root->data)
        InsertBST(root->lchild,s);
    else
        InsertBST(root->rchild,s);
}   

BiSortTree::BiSortTree(int r[],int n)
{
    for(int i=0;i<n;i++)
    {
        BiNode<int>s=new BiNode<int>;
        s->data=r[i];
        s->lchild=s->rchild=NULL;
        InsertBST(root,s);
    }
}
//在二叉排序树中删除一个节点f的左孩子节点p的算法:
//1.若节点p是叶子,则直接删除节点p
//2.若节点p只有左子树,则需重接p的左子树;若节点p只有右子树,则需重接p的右子树
//3.若节点p的左右子树都不为空,则
//  3.1查找节点p的右子树上的最左下节点s以及节点s的双亲节点par
//  3.2将节点s的数据域替换到被删除节点p的数据域
//  3.3若节点p的右孩子无左子树,则将s的右子树接到par的右子树上;否则将s的右子树接到节点par的左子树上
//  3.4删除节点s;
void BiSortTree::DeleteBST(BiNode<int>*p,BiNode<int>*f)
{
    if((p->lchild==NULL)&&(p->rchild)==NULL)
    {
        f->lchild=NULL;
        delete p;
    }
    else if(p->rchild==NULL)
    {
        f->lchild=p->lchild;
        delete p;
    }
    else if(p->lchild==NULL)
    {
        f->lchild=p->rchild;
        delete p;
    }
    else{
        BiNode<int>*par=p;
        BiNode<int>*s=p->rchild;
        while(s->lchild!=NULL)
        {
            par=s;
            s=s->lchild
        }
        p->data=s->data;
        if(par==p)
            par->rchild=s->rchild;
        else
            par->lchild=s->rchild;
        delete s;

    }

}
BiNode<int>*BiSortTree::SearchBST(BiNode<int>*root,int k)
{
    if(root==NULL)
        return NULL;
    else if(root->data==k)
        return root;
    else if(root->date>k)
        return SearchBST(root->lchild,k);
    else if(root->data<k)
        return SearchBST(root->rchild,k);
}

给定值的比较次数等于给定值节点在二叉排序树中的层数。如果二叉排序树是平衡的,则n个节点的二叉排序树的高度为Log 2n+1,其查找效率为O(Log 2n),近似于折半查找。如果二叉排序树完全不平衡,则其深度可达到n,查找效率为O(n),退化为顺序查找。一般的,二叉排序树的查找性能在O(Log 2n)到O(n)之间。因此,为了获得较好的查找性能,就要构造一棵平衡的二叉排序树。

猜你喜欢

转载自blog.csdn.net/li_huai_dong/article/details/79911069