所谓逆序对为对于数组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;
}