算法导论第十四章习题14.1-7利用顺序统计数统计数组中的逆序数

所谓逆序对为对于数组a,如果i<j,且a[i]>a[j],则这两个数即为一个逆序对。数组的逆序数即为数组中逆序对的个数。在第二章中的2-4利用合并排序的思路在O(nlgn)时间内统计数组a[n]的逆序数(具体方法可以参考之前写的博客算法导论第二章课后习题代码实现)。在本文中,将利用顺序统计数在O(nlgn)时间内统计逆序数。

思路是:在每插入一个元素时,计算出该元素在当前树中的秩n(即为第几小元素),然后size(root)-n即为比当前元素大的节点个数,在没插入一个节点时对这些个数相加即为数组的逆序数。部分代码如下:

	int Insert(int num)
	{
		BRTreeNode* node=new BRTreeNode(num,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 0;
		}
		while(p!=nil)
		{
			if(p->key==num)
			{
				cout<<num<<"  has exist!"<<endl;
				return 0;
			}
			else if(p->key>num)
			{
				q=p;
				p=p->left;
			}
			else
			{
				q=p;
				p=p->right;
			}
		}
		if(q->key>num)
		{
			q->left=node;
			node->parent=q;
		}
		else
		{
			q->right=node;
			node->parent=q;
		}
		RBInsertAdjust(node);
		SizeAdjust(root);
		//计算比node节点大的元素个数,并返回
		int result=RankoftheNode(node);
		result=root->size-result;
		return result;
	}


插入元素node时,返回值result即为比node节点大的元素的个数。

在主函数中添加的循环计算出了总的逆序数:

for(i=0;i<8;i++)
	{
		num+=tree.Insert(a[i]);
	}
	cout<<num<<endl;


 

输出的num即为逆序数。

本文的整体代码参考如下,其中大部分代码为顺序统计树重大 相关操作,与本题没有相关性:

BinTreeNode.h

#include<iostream>
using namespace std;
class BRTree;
class BRTreeNode
{
private:
	friend BRTree;
	int key;
	bool color;
	BRTreeNode* left;
	BRTreeNode* right;
	BRTreeNode* parent;
	int size;
public:
	BRTreeNode():key(-1),size(0),color(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,bool flag):key(num),color(flag),size(1),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<<" ";
			this->right->Inorder();
		}
	}
	void Preorder()
	{
		if(this!=NULL)
		{
			cout<<this->key<<" ";
			this->left->Preorder();
			this->right->Preorder();
		}
	}
	void Postorder()
	{
		if(this!=NULL)
		{
			this->left->Postorder();
			this->right->Postorder();
			cout<<this->key<<" ";
		}
	}
	void MakeEmpty()
	{
		if(this!=NULL)
		{
			this->left->MakeEmpty();
			this->right->MakeEmpty();
			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);
	}
};


 

BinTree.h

#include"BRTreeNode.h"
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;
	}
	~BRTree()
	{
		MakeEmpty(root);
		delete 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;
		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;
		return 1;
	}
	void SizeAdjust(BRTreeNode*node)
	{
		if(node!=nil)
		{
			SizeAdjust(node->left);
			SizeAdjust(node->right);
			node->size=node->left->size+node->right->size+1;
			
		}
	}
	int Insert(int num)
	{
		BRTreeNode* node=new BRTreeNode(num,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 0;
		}
		while(p!=nil)
		{
			if(p->key==num)
			{
				cout<<num<<"  has exist!"<<endl;
				return 0;
			}
			else if(p->key>num)
			{
				q=p;
				p=p->left;
			}
			else
			{
				q=p;
				p=p->right;
			}
		}
		if(q->key>num)
		{
			q->left=node;
			node->parent=q;
		}
		else
		{
			q->right=node;
			node->parent=q;
		}
		RBInsertAdjust(node);
		SizeAdjust(root);
		//计算比node节点大的元素个数,并返回
		int result=RankoftheNode(node);
		result=root->size-result;
		return result;
	}
	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;
		if(y!=z)
		{
			z->key=y->key;
		}
		if(y->color==0)
		{
			RBTreeFixup(x);
		}
		SizeAdjust(root);
		return 1;
	}
	BRTreeNode*GetIthnode(BRTreeNode*node,int num)
	{
		int r=node->left->size+1;
		if(r==num)
		{
			return node;
		}
		else if(r>num)
		{
			return GetIthnode(node->left,num);
		}
		else
		{
			return GetIthnode(node->right,num-r);
		}
	}
	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;
	}
	//求的中序遍历中节点node出现的位置,非递归实现
	int RankoftheNode(BRTreeNode* x)
	{
		int r=x->left->size+1;
		BRTreeNode*p=x;
		while(p!=root)
		{
			if(p==p->parent->right)
			{
				r+=p->parent->left->size+1;
				
			}	
			p=p->parent;
		}
		return r;
	}
	//求的中序遍历中节点node出现的位置,递归实现
	int Rank(BRTreeNode* x)
	{
		BRTreeNode*p=x;
		int r=x->left->size+1;
		if(p==root)
			return r;
		else if(p==p->parent->right)
		{
			return Rank(p->parent)+r;
		}
		return r;
	}
};


 

main.cpp

#include"BRTree.h"
int main()
{
	BRTree tree;
	int a[8]={14,11,2,1,7,5,8,15};
	int i,num=0;
	for(i=0;i<8;i++)
	{
		num+=tree.Insert(a[i]);
	}
	cout<<num<<endl;
	tree.Inorder(tree.Getroot());
	cout<<endl;
	tree.Insert(4);
	tree.Inorder(tree.Getroot());
	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;
	cout<<tree.GetIthnode(tree.Getroot(),7)->Getkey()<<endl;
	cout<<endl;
	cout<<tree.Rank(tree.Search(15))<<endl;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值