红黑树

红黑树与二叉查找树相似,只是增加了一个字段来表示节点是红色还是黑色。为什么要增加这个属性呢?在二叉查找树中,如果节点按照从大到小或从小到大插入,二叉查找树就变成了一个链表。因此增加这个字段来调整树的高度避免它变成一个链表,为什么能避免?

首先看一下红黑树的属性:

1. 每个节点非红即黑。

2. 根节点为黑色。

3. 每个叶子节点都为黑色。

4. 如果一个节点为红色,那么它的子女必须为黑色。

5. 任意节点到它子树叶子节点所有路径都必须包含相同黑色节点个数。

由此可得出定理:

A red-black tree with n internal nodes has height at most 2 lg(n + 1).

 证明:存在任一个节点x,把x到达任一个叶子节点的路径中的黑节点的个数称为黑高度,设为bh(x)。首先证明x的子树中至少有2bh(x)-1个节点,用归纳法证明。根据x和他子女的红黑属性,可得出x子女的黑高度为bh(x)或bh(x)-1,可假设子女的子树至少有2bh(x)-1个节点,那么x就至少有2bh(x)-1-1+2bh(x)-1-1+1=2bh(x)-1个节点。设n>=2bh(x)-1,则bh(x)<=2lg(n+1)。因此红黑属性一定程度保证了树的平衡性。

红黑树实现:

红黑树的实现与二叉查找树的实现相似,只是在插入删除的时候加入调整函数以保证红黑树的属性。

RBTree.h:

// RBTree.h
#pragma  once

typedef 
enum  _color
... COLOR;

class  RBNode
{
public:
    RBNode(
void):key(0),parent(NULL),left(NULL),right(NULL),color(BLACK){}
    RBNode(
int value);
public:
    
~RBNode(void);
public:
    
int key;
    RBNode 
*parent;
    RBNode 
*left;
    RBNode 
*right;
    COLOR color;
}
;

class  RBTree
{
public:
    RBTree(
void);
    
void Insert(int value);
    
void Delete(int value);
    RBNode
* Max(RBNode *pNode);
    RBNode
* Min(RBNode *pNode);
    
void Dispose(RBNode *pNode);
public:
    
~RBTree(void);
private:
    
void LeftRotate(RBNode *pNode);
    
void RightRotate(RBNode *pNode);
    
void InsertFixUp(RBNode *pNode);
    RBNode
* Successor(RBNode *pNode);
    
void DeleteFixUp(RBNode *pNode);
private:
    RBNode
* m_pRoot;
    
static RBNode *nil;
}
;

RBTree.cpp:

 

#include  " StdAfx.h "
#include 
" RBTree.h "

RBNode::RBNode(
int  value)
{
    key
=value;
    parent
=NULL;
    left
=NULL;
    right
=NULL;
    color
=RED;
}


RBNode::
~ RBNode()
{
}


RBNode
*  RBTree::nil = new  RBNode();

RBTree::RBTree(
void )
{
    m_pRoot
=NULL;
}


RBTree::
~ RBTree( void )
{
    Dispose(m_pRoot);
}


void  RBTree::Dispose(RBNode  * pNode)
{
    
if(pNode->left!=nil)
        Dispose(pNode
->left);
    
if(pNode->right!=nil)
        Dispose(pNode
->right);
    delete pNode;
}


void  RBTree::Insert( int  value)
{
    
if(m_pRoot==NULL)
    
{
        RBNode 
*pNew=new RBNode();
        pNew
->key=value;
        pNew
->parent=nil;
        pNew
->left=nil;
        pNew
->right=nil;
        m_pRoot
=pNew;
    }

    
else
    
{
        RBNode 
*py;
        RBNode 
*px=m_pRoot;
        
while(px!=nil)
        
{
            py
=px;
            
if(value<px->key)
            
{
                px
=px->left;
            }

            
else if(value>px->key)
            
{
                px
=px->right;
            }

            
else
            
{
                py
=nil;
            }

        }

        
if(py!=nil)
        
{
            RBNode 
*pNew=new RBNode(value);
            pNew
->parent=py;
            
if(value<py->key)
            
{
                py
->left=pNew;
            }

            
else
            
{
                py
->right=pNew;
            }

            pNew
->left=nil;
            pNew
->right=nil;
            pNew
->color=RED;

            
if(py!=this->m_pRoot)
                InsertFixUp(pNew);
        }

    }

}


void  RBTree::LeftRotate(RBNode  * pNode)
{
    
if(pNode->right!=nil)
    
{
        RBNode 
*y=pNode->right;
        pNode
->right=y->left;
        
if(nil!=y->left)
        
{
            y
->left->parent=pNode;
        }

        y
->parent=pNode->parent;
        
if(nil==pNode->parent)
        
{
            m_pRoot
=y;
        }

        
else if(pNode=pNode->parent->left)
        
{
            pNode
->parent->left=y;
        }

        
else
        
{
            pNode
->parent->right=y;
        }

        y
->left=pNode;
        pNode
->parent=y;
    }

}


void  RBTree::RightRotate(RBNode  * pNode)
{
    
if(nil!=pNode->left)
    
{
        RBNode 
*y=pNode->left;
        pNode
->left=y->right;
        
if(nil!=y->right)
        
{
            y
->right->parent=pNode;
        }

        y
->parent=pNode->parent;
        
if(nil==pNode->parent)
        
{
            m_pRoot
=y;
        }

        
else if(pNode->parent->left==pNode)
        
{
            pNode
->parent->left=y;
        }

        
else
        
{
            pNode
->parent->right=y;
        }

        y
->right=pNode;
        pNode
->parent=y;
    }

}


void  RBTree::InsertFixUp(RBNode  * pNode)
{
    
while(pNode->parent->color==RED)
    
{
        RBNode 
*py;
        
if(pNode->parent==pNode->parent->parent->left)
        
{
            py
=pNode->parent->parent->right;
            
//Case 1: z's uncle y is red
            if(py->color==RED)
            
{
                pNode
->parent->color=BLACK;
                py
->color=BLACK;
                pNode
->parent->parent->color=RED;
                pNode
=pNode->parent->parent;
            }

            
else
            
{
                
//Case 2: z's uncle y is black and z is a right child
                if(pNode==pNode->parent->right)
                
{
                    pNode
=pNode->parent;
                    
this->LeftRotate(pNode);
                }

                
//Case 3: z's uncle y is black and z is a left child
                pNode->parent->color=BLACK;
                pNode
->parent->parent->color=RED;
                
this->RightRotate(pNode->parent->parent);
            }

        }

        
else
        
{
            py
=pNode->parent->parent->left;
            
if(py->color==RED)
            
{
                pNode
->parent->color=BLACK;
                py
->color=BLACK;
                pNode
->parent->parent->color=RED;
            }

            
else
            
{
                
if(pNode==pNode->parent->left)
                
{
                    pNode
=pNode->parent;
                    
this->RightRotate(pNode);
                }

                pNode
->parent->color=BLACK;
                pNode
->parent->parent->color=RED;
                
this->LeftRotate(pNode->parent->parent);
            }

        }

    }

    
this->m_pRoot->color=BLACK;
}


RBNode
*  RBTree::Max(RBNode  * pNode)
{
    
while(pNode->left!=nil)
    
{
        pNode
=pNode->left;
    }

    
return pNode;
}


RBNode
*  RBTree::Min(RBNode  * pNode)
{
    
while(pNode->right!=nil)
    
{
        pNode
=pNode->right;
    }

    
return pNode;
}


RBNode
*  RBTree::Successor(RBNode  * pNode)
{
    
if(pNode->right!=nil)
        
return Min(pNode->right);
    RBNode
* py=pNode->parent;
    
while(py!=nil&&pNode==py->right)
    
{
        pNode
=py;
        py
=py->parent;
    }

    
return py;
}


RBNode
*  RBTree::Find( int  value)
{
    
if(this->m_pRoot==nil)
        
return NULL;
    
else
    
{
        RBNode 
*pNode=this->m_pRoot;
        
while(pNode->key!=value&&pNode!=nil)
        
{
            
if(value<pNode->key)
            
{
                pNode
=pNode->left;
            }

            
else
            
{
                pNode
=pNode->right;
            }

        }

        
return pNode==nil?NULL:pNode;
    }

}


void  RBTree::Delete( int  value)
{
    RBNode 
*pNode=Find(value);
    RBNode 
*py,*px;
    
if(pNode!=NULL)
    
{
        
if(pNode->left==nil||pNode->right==nil)
        
{
            py
=pNode;
        }

        
else
        
{
            py
=this->Successor(pNode);
        }

        
if(py->left!=nil)
        
{
            px
=py->left;
        }

        
else
        
{
            px
=py->right;
        }

        px
->parent=py->parent;
        
if(py->parent==nil)
        
{
            m_pRoot
=px;
        }

        
else if(py->parent->left=py)
        
{
            py
->parent->left=px;
        }

        
else
        
{
            py
->parent->right=px;
        }

        
bool isFix=py->color==BLACK?true:false;
        
if(py==pNode)
        
{
            py
->parent=pNode->parent;
            py
->left=pNode->left;
            py
->right=pNode->right;
            py
->color=pNode->color;
            delete pNode;
        }

        
if(isFix)
            DeleteFixUp(px);
    }

}


void  RBTree::DeleteFixUp(RBNode  * pNode)
{
    
if(pNode==NULL||pNode==nil)
        
return;
    
while(pNode!=this->m_pRoot&&pNode->color==BLACK)
    
{
        
if(pNode==pNode->parent->left)
        
{
            RBNode 
*pw=pNode->parent->right;
            
//case1:x's sibling w is red
            if(pw->color=RED)
            
{
                pNode
->parent->color=RED;
                pw
->color=BLACK;
                
this->LeftRotate(pNode->parent);
                pw
=pNode->parent->right;
            }

            
//case2:x's sibling w is black, and both of w's children are black
            if(pw->left->color==BLACK&&pw->right->color==BLACK)
            
{
                pw
->color=RED;
                pNode
=pNode->parent;
            }

            
else
            
{
                
//case3:x's sibling w is black, w's left child is red, and w's right child is black
                if(pw->right->color==BLACK)
                
{
                    pw
->left->color=BLACK;
                    pw
->color=RED;
                    
this->RightRotate(pw);
                    pw
=pNode->parent->right;
                }

                
//case4:x's sibling w is black, and w's right child is red
                pw->color=pNode->parent->color;
                pNode
->parent->color=BLACK;
                pw
->right->color=BLACK;
                
this->LeftRotate(pNode->parent);
                pNode
=this->m_pRoot;
            }

        }

        
else
        
{
            RBNode 
*pw=pNode->parent->left;
            
if(pw->color==RED)
            
{
                pNode
->parent->color=RED;
                pw
->color=BLACK;
                
this->RightRotate(pNode->parent);
                pw
=pNode->parent->left;
            }

            
if(pw->right->color==BLACK&&pw->left->color==BLACK)
            
{
                pw
->color=RED;
                pNode
=pNode->parent;
            }

            
else
            
{
                
if(pw->left->color==BLACK)
                
{
                    pw
->color=RED;
                    pw
->left->color=BLACK;
                    
this->LeftRotate(pw);
                    pw
=pNode->parent->left;
                }

                pw
->color=pNode->parent->color;
                pNode
->parent->color=BLACK;
                pw
->left->color=RED;
                
this->RightRotate(pNode);
                pNode
=this->m_pRoot;
            }

        }

    }

    pNode
->color=BLACK;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值