完整的C++实现算法导论十三章红黑树以及十四章中的顺序统计树

#include<iostream>
using namespace std;
class BRTree;
class BRTreeNode{
private:
	friend class BRTree;
	int key;
	bool  color;
	int size;
	BRTreeNode *left;
	BRTreeNode *right;
	BRTreeNode *parent;
public:
	//创建一个默认构造函数
	BRTreeNode():key(-1),color(0),size(0),left(NULL),right(NULL),parent(NULL){}
	//创建一个拷贝构造函数
	BRTreeNode(BRTreeNode *node):key(node->key),color(node->color),size(node->size),left(node->left),right(node->right),parent(node->parent){}
	//创建一个含有参数的构造函数
	BRTreeNode(int num,int flag,int value):key(num),color(flag),size(value),left(NULL),right(NULL),parent(NULL){}
	//下面创建一个析构函数
	~BRTreeNode()
	{}
	//下面定义一个返回结点值的函数
	int getkey()
	{
		return key;
	}
	//下面定义一个返回标记的函数
	bool getcolor()
	{
		return this->color;
	}
	 BRTreeNode* GetLeft()
    {
        return this->left;
    }
    BRTreeNode* Getright()
    {
        return this->right;
    }
    BRTreeNode* Getparent()
    {
        return this->parent;
    }
	void inorder()
	{
		if(this!=NULL)
		{
			this->left->inorder();
			cout<<"中序遍历的值是"<<this->key<<endl;
			this->right->inorder();
		}
	}
	//下面定义一个前序遍历的函数
	void preorder()
	{
		if(this!=NULL)
		{
			cout<<"前序遍历的结果是"<<this->key<<endl;
			this->left->preorder();
			this->right->preorder();
		}
	}
	//6
	  void Postorder()
    {
        if(this!=NULL)
        {
            this->left->Postorder();
            this->right->Postorder();
            cout<<this->key<<" ";
        }
    }
    void make_empty()
	{
		if(this!=NULL)
		{
			this->left->make_empty();
			this->right->make_empty();
			delete this;
		}
	}
	int getheight()
	{
		int L,R;
		if(this==NULL)
		{
			return 0;
		}
		L=this->left->getheight();
		R=this->right->getheight();
		return 1+(L>R)?L:R;
	}

};

class BRTree{
private:
	BRTreeNode *root;
	BRTreeNode *nil;
public:
	BRTree():nil(new BRTreeNode())
	{
		nil->color=0;
		nil->key=-1;
		nil->left=nil->right=nil->parent=NULL;
		root=nil;
	}
	//下面定义一个以清空node为根结点的树
	 void MakeEmpty(BRTreeNode*node)
    {
        if(node!=nil)
        {
            MakeEmpty(node->left);
            MakeEmpty(node->right);
            delete node;
        }
    }
    int Getkey(BRTreeNode* node)
    {
		return node->getkey();
    }
    bool Getcolor(BRTreeNode* node)
    {
		return node->getcolor();
    }
    BRTreeNode* Getroot()
    {
        return root;
    }
    BRTreeNode* GetParent(BRTreeNode*node)
    {
        return node->parent;
    }
    int GetHeight(BRTreeNode *node)
    {
        int L,R;
        if(node==nil)
            return 0;
        L=GetHeight(node->left);
        R=GetHeight(node->right);
        return 1+(L>R? L:R);
    }
    void Inorder(BRTreeNode *node)
    {
        if(node!=nil)
        {
            Inorder(node->left);
            cout<<node->key<<" ";
            Inorder(node->right);
        }
    }
    void Preorder(BRTreeNode *node)
    {
        if(node!=nil)
        {
            cout<<node->key<<" ";
            Preorder(node->left);
            Preorder(node->right);
        }
    }
    void Posetorder(BRTreeNode*node)
    {
        if(node!=nil)
        {
            Posetorder(node->left);
            Posetorder(node->right);
            cout<<node->key<<" ";
        }
    }
    //左旋节点node
    bool LeftRotate(BRTreeNode* node)
    {
        BRTreeNode *y;
        if(node->right==nil)
        {
            cout<<"can't left rotate!"<<endl;
            return 0;
        }
        y=node->right;
        node->right=y->left;
        if(y->left!=nil)
        {
            y->left->parent=node;
        }
        y->parent=node->parent;
        if(node->parent==nil)
        {
            root=y;
        }
        else if(node->parent->left==node)
        {
            node->parent->left=y;
        }
        else
        {
            node->parent->right=y;
        }
        y->left=node;
        node->parent=y;
		//调整size域的大小
		y->size=node->size;
		node->size=node->left->size+node->right->size;
        return 1;
    }  

	  //下面定义的是一个右旋函数
     bool RightRotate(BRTreeNode* node)
      {
        if(node->left==nil)
        {
            cout<<"can't rightrotate!"<<endl;
            return 0;
        }
        BRTreeNode* x;
        x=node->left;
        node->left=x->right;
        if(x->right!=nil)
        {
            x->right->parent=node;
        }
        x->parent=node->parent;
        if(node->parent==nil)
        {
            root=x;
        }
        else if(node->parent->left==node)
        {
            node->parent->left=x;
        }
        else
        {
            node->parent->right=x;
        }
        node->parent=x;
        x->right=node;
		x->size=node->size;
		node->size=node->left->size+node->right->size;
        return 1;
      }  

	//插入一个值
	 void Insert(int num)
    {
        BRTreeNode* node=new BRTreeNode(num,1,1);
        node->left=nil;
        node->right=nil;
        node->parent=nil;
        BRTreeNode* p=root,*q=nil;
        if(root==nil)
        {
            node->color=0;
            root=node;
            root->left=root->right=root->parent=nil;
			root->size=1;
            return ;
        }
        while(p!=nil)
        {
            if(p->key==num)
            {
                cout<<num<<"  has exist!"<<endl;
                return ;
            } 

            else if(p->key>num)
			{   p->size+=1;
				q=p;
                p=p->left;
            }
            else
            {  p->size+=1;
                q=p;
                p=p->right;
            }
        } 

        if(q->key>num)
        {
            q->left=node;
            node->parent=q;
        }
        else
        {
            q->right=node;
            node->parent=q;
        }
        RBInsertAdjust(node);
    }
	 void RBInsertAdjust(BRTreeNode* node)
    {
        BRTreeNode* y;
        while(node->parent->color==1)
        {
            if(node->parent==node->parent->parent->left)
            {
                y=node->parent->parent->right;
                if(y->color==1)
                {
                    node->parent->color=0;
                    y->color=0;
                    y->parent->color=1;
                    node=node->parent->parent;
                }
                //此时y的颜色是黑色
                else
                {
                    //第二种情况
                    if(node==node->parent->right)
                    {
                        node=node->parent;
                        LeftRotate(node);
                    }
                    //第三种情况
                    node->parent->color=0;
                    node->parent->parent->color=1;
                    RightRotate(node->parent->parent);
                }
            }
            else
            {
                y=node->parent->parent->left;
                if(y->color==1)
                {
                    node->parent->color=0;
                    y->color=0;
                    y->parent->color=1;
                    node=node->parent->parent;
                }
                else
                {
                    if(node==node->parent->left)
                    {
                        node=node->parent;
                        RightRotate(node);
                    }
                    node->parent->color=0;
                    node->parent->parent->color=1;
                    LeftRotate(node->parent->parent);
                }
            }
        }
        root->color=0;
    }
	 //搜索某个值
	  BRTreeNode* Search(int num)
    {
        BRTreeNode* p=root;
        while(p!=nil)
        {
            if(p->key==num)
            {
                return p;
            }
            else if(p->key>num)
            {
                p=p->left;
            }
            else
            {
                p=p->right;
            }
        }
        cout<<"there is no "<<num<<" in this tree!"<<endl;
        return nil;
    }
    //获取以node节点为根节点的树的最小元素,并返回该最小值
	  int Minnum(BRTreeNode*node)
    {
        BRTreeNode*p=node;
        while(p->left!=nil)
        {
            p=p->left;
        }
        return p->key;
    }
    //获取以node节点为根节点的树的最da元素,并返回该最da值
    int Maxnum(BRTreeNode*node)
    {
        BRTreeNode*p=node;
        while(p->right!=nil)
        {
            p=p->right;
        }
        return p->key;
    }
    //获取以node节点为根节点的树的最小元素,并返回该节点
    BRTreeNode* MinNum(BRTreeNode*node)
    {
        BRTreeNode*p=node;
        while(p->left!=nil)
        {
            p=p->left;
        }
        return p;
    }
    //获取以node节点为根节点的树的最大元素
    BRTreeNode* MaxNum(BRTreeNode*node)
    {
        BRTreeNode*p=node;
        while(p->right!=nil)
        {
            p=p->right;
        }
        return p;
    }  

	 BRTreeNode*InorderSuccessor(BRTreeNode*node)
    {
        if(node->right!=nil)
        {
            return MinNum(node->right);
        }
        else
        {
            BRTreeNode*p=GetParent(node);
            while(p&&node==p->right)
            {
                node=p;
                p=GetParent(node);
            }
            return p;
        }
    }
    //中序遍历的前趋
    BRTreeNode*InordePredecessor(BRTreeNode*node)
    {
        if(node->left!=nil)
        {
            return MaxNum(node->left);
        }
        else
        {
            BRTreeNode*p=GetParent(node);
            while(p&&node==p->left)
            {
                node=p;
                p=GetParent(node);
            }
            return p;
        }
    }
    bool Delete(int num)
    {
        BRTreeNode*z,*y,*x;
        //寻找key值为num的节点p
        z=Search(num);
        //如果没有该节点则返回0
        if(z==nil)
        {
            return 0;
        }
        if(z->left==nil||z->right==nil)
        {
            y=z;
        }
        else
            y=InorderSuccessor(z);
        if(y->left!=nil)
            x=y->left;
        else
            x=y->right;
        x->parent=y->parent;
        if(x->parent==nil)
            root=x;
        else if(y=y->parent->left)
            y->parent->left=x;
        else
            y->parent->right=x;
		while(y!=root)
		{
			y->parent->size=y->parent->size-1;
			y=y->parent;
		}
        if(y!=z)
        {
            z->key=y->key;
        }
        if(y->color==0)
        {
            RBTreeFixup(x);
        }
        return 1;
    }
    void RBTreeFixup(BRTreeNode* x)
    {
        BRTreeNode *w;
        while(x!=root&&x->color==0)
        {
            if(x==x->parent->left)
            {
                w=x->parent->right;
                if(w->color==1)
                {
                    w->color=0;
                    x->parent->color=1;
                    LeftRotate(x->parent);
                    w=x->parent->right;
                }
                if(w->left->color==0&&w->right->color==0)
                {
                    w->color=1;
                    x=x->parent;
                }
                else
                {
                    if(w->right->color==0)
                    {
                        w->color=1;
                        RightRotate(w);
                        w=x->parent->right;
                    }
                    w->color=x->parent->color;
                    x->parent->color=0;
                    w->right->color=0;
                    LeftRotate(x->parent);
                    x=root;
                }
            }
            else
            {
                w=x->parent->left;
                if(w->color==1)
                {
                    w->color=0;
                    x->parent->color=1;
                    RightRotate(x->parent);
                    w=x->parent->left;
                }
                if(w->right->color==0&&w->left->color==0)
                {
                    w->color=1;
                    x=x->parent;
                }
                else
                {
                    if(w->left->color==0)
                    {
                        w->color=1;
                        LeftRotate(w);
                        w=x->parent->left;
                    }
                    w->color=x->parent->color;
                    x->parent->color=0;
                    w->left->color=0;
                    RightRotate(x->parent);
                    x=root;
                }
            }
        }
        x->color=0;
    }
	//下面根据统计秩来找出相应的元素,其实也就是中序排列所处的位置

	~BRTree()
	{
		MakeEmpty(root);
		delete nil;
	}

	BRTreeNode *os_select(BRTreeNode *startnode,int i)
	{
		int r=startnode->size+1;
		if(r==i)
		{
			return startnode;
		}
		else if(i<r)
		{
			return os_select(startnode->left,i);
		}
		else
		{
			return os_select(startnode->right,i-r);
		}
	}
	//下面定义一个给定结点的指针来找出其秩的函数
	int os_rank(BRTreeNode *startnode)
	{
		int r=startnode->left->size+1;
		BRTreeNode *y=startnode;
		while(y!=root)
		{
			if(y==y->parent->right)
			{
				r+=y->parent->left->size+1;
			}
			y=y->parent;
		}
		return r;
	}

};
int main()
{   

	BRTree tree;
    int a[8]={11,2,1,7,5,8,14,15};
    int i;
    for(i=0;i<8;i++)
    {
        tree.Insert(a[i]);
    }
    tree.Inorder(tree.Getroot());  //输出的结果是从小到大输出,其结果是1 2 5 7 8 11 14 15;
    cout<<endl;
    /*tree.Insert(4);  //插入一个的值是为4的;
    tree.Inorder(tree.Getroot());  //中序输出插入4之后序列的结果为 1 2 4 5 7 8 11 14 15
    cout<<endl;
    tree.Insert(6);
    tree.Inorder(tree.Getroot());
    cout<<endl;
    tree.Insert(3);
    tree.Inorder(tree.Getroot());
    cout<<endl;
    cout<<tree.GetHeight(tree.Getroot());
    cout<<endl;
    tree.Delete(2);
    tree.Inorder(tree.Getroot());
    cout<<endl;  */
	tree.Insert(4);
	 tree.Inorder(tree.Getroot());
	cout<<tree.os_rank(tree.Search(5))<<endl;

	system("pause");
	return 0;
}

时间: 2024-10-11 23:16:12

完整的C++实现算法导论十三章红黑树以及十四章中的顺序统计树的相关文章

算法导论第十三章 红黑树

写在前面:这一章真的把我害惨了,之前至少尝试看过3遍,每次看之前都下定决定一定要把它拿下,可是由于内容较多,深度够深,以致于每次要不是中途有什么事放弃了就跳过了,要不是花时间太多仍然不能理解而放弃.这次总算挺过来了,前后零零散散的时间加起来差不多也有两天时间.这次能坚持下来并攻克,我想大概有这么几个原因吧:第一是之前下定的决心要写一个最新版<算法导论>的读书笔记,之前几章都坚持写了,不能让这个成为拦路虎,即使再难再花时间都要弄懂:第二是通过前面几章的动手实践,发现自己的理解能力.动手能力都进步

算法导论 第十三章 红黑树(python)-1插入

红黑树是上一章二叉搜索树的改进,实现一种平衡 ,保证不会出现二叉树变链表的情况,基本动态集合操作的时间复杂度为O(lgn) 实际用途:c++stl中的set,map是用他实现的 红黑树的性质: 1.每个结点或是红色的,或是黑色的 2.跟结点是黑色的 3.每个叶结点(NIL)是黑色 4.如果一个结点是红色的,则它的两个结点都是黑色的 5.对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同的数目的黑色结点(数目被称为黑高bh(x)) 如下图: (T.nil 哨兵后面被忽略 None) 红

算法导论 第13章 红黑树

二叉查找树的基本操作包括搜索.插入.删除.取最大和最小值等都能够在O(h)时间复杂度内实现,因此能在期望时间O(lgn)下实现,但是二叉查找树的平衡性在这些操作中并没有得到维护,因此其高度可能会变得很高,当其高度较高时,而二叉查找树的性能就未必比链表好了,所以二叉查找树的集合操作是期望时间O(lgn),最坏情况下为O(n). 红黑树也是一种二叉查找树,它拥有二叉查找树的性质,同时红黑树还有其它一些特殊性质,这使得红黑树的动态集合基本操作在最坏情况下也为O(lgn),红黑树通过给节点增加颜色和其它

算法导论笔记——第十二~十四章 数据结构(二)树

第十二章 二叉搜索树 >=左子树的所有key,<=右子树的所有key 在一棵高度为h的二叉搜索树上,动态集合上的操作SEARCH,MINIMUM,MAXIMUM,SUCCESSOR,PREDECESSOR,INSERT和DELETE可以在O(h)时间内完成. h>=(lgn向下取整) 和快速排序算法一样,其平均性能更接近于最好情形. 随机构建二叉搜索树期望高度为O(lgn). 各种操作请自行查阅. 第十三章 红黑树 是一种(近似)平衡的二叉搜索树.可以保证在最坏情况下基本动态集合操作的时

算法导论读书笔记-第十四章-数据结构的扩张

算法导论第14章 数据结构的扩张 一些工程应用需要的只是标准数据结构, 但也有许多其他的应用需要对现有数据结构进行少许的创新和改造, 但是只在很少情况下需要创造出全新类型的数据结构, 更经常的是通过存储额外信息的方法来扩张一种标准的数据结构, 然后对这种数据结构编写新的操作来支持所需要的应用. 但是对数据结构的扩张并不总是简单直接的, 因为新的信息必须要能被该数据结构上的常规操作更新和维护. 14.1 动态顺序统计 顺序统计树(order-static tree) : 在红黑树的基础上, 在每个

CSS3秘笈复习:十三章&amp;十四章&amp;十五章&amp;十六章&amp;十七章

第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮动元素.关键字:left.right或both. (2).浮动外围元素:让包含浮动元素的<div>也浮动.选择这种方法一定要在浮动容器后面的任何元素中添加一个clear属性,确保浮动元素落到容器的下方. (3).利用overflow : hidden.另一种常见的方法是在外围的样式中添加以下属性:

第十三章 红黑树

R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). 红黑树的特性:(1)每个节点或者是黑色,或者是红色.(2)根节点是黑色.(3)每个叶子节点(NIL)是黑色. [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!](4)如果一个节点是红色的,则它的子节点必须是黑色的.(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点.

中国游戏辅助写手回忆录[十三~十四章]

这是分开章节的版本,追更阅读的朋友可以从这个地址下载标题所示的更新章节 没有阅读的过朋友还请请下载置顶的完整版,从头阅读. 十三章下载地址:http://pan.baidu.com/s/1G11RC 十四章下载地址:http://pan.baidu.com/s/1kTMoSEb

2019-2020-1学期 20192415 《网络空间安全专业导论》第一周学习总结 第四章

2019-2020-1学期 20192415 <网络空间安全专业导论>第二周学习总结 第四章 门与电路 硬件元件,用电信号表示操作二进制值 4.1 计算机与电学 信号电平区分信号的值: 0~2伏为低电压,由二进制数字0表示 2~5伏为高电压,由二进制数字1表示 门(gate):对电信号执行基本运算的设备. 电路(circuit):相互关联的门组合,用于实现特定的逻辑函数. 表示法: 布尔代数--用数学符号定义和操作逻辑电路 逻辑框图--图形化表示(特定) 真值表--列举,定义功能 注:三种表示