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