第十四章 数据结构扩张 动态顺序统计部分代码
来源:互联网 发布:金钻js防水 编辑:程序博客网 时间:2024/05/16 00:35
在这一章中,动态顺序统计和区间树被举例用来显示怎样去扩张一个数据结构。一般来说,扩张一个数据结构分为以下四个步骤:
- 选择一种基础数据结构;
- 确定基础数据结构中要维护的附加信息;
- 检验基础数据结构上的基本修改操作能否维护附加信息;
- 设计一些新操作。
当然设计一个数据结构的扩张,没有那么顺利,永远包含着试探和纠错。下面给出基于红黑树的动态顺序统计和区间树的代码。
动态顺序统计:
下面代码给出了左旋,右旋,恢复插入引起的红黑树性质的破坏,插入,恢复删除引起的红黑树性质的破坏,删除,查找第i小关键字,返回一个元素的秩。
左旋:
template<class Type>void orderStatisticTree<Type>::leftRotate(node* x){ node* y=x->right; y->parent=x->parent; if(x->parent==nullNode) root=y; else if(x==x->parent->left) x->parent->left=y; else x->parent->right=y; x->right=y->left; if(y->left!=nullNode) x->right->parent=x; y->left=x; x->parent=y;//上面代码和红黑树右旋代码一样,下面两行代码用来维护附加信息size。 y->size=x->size; x->size=x->left->size+x->right->size+1;}
右旋:
template<class Type>void orderStatisticTree<Type>::rightRotate(node* x){ node* y=x->left; y->parent=x->parent; if(x->parent==nullNode) root=y; else if(x==x->parent->left) x->parent->left=y; else x->parent->right=y; x->left=y->right; if(y->right!=nullNode) x->left->parent=x; y->right=x; x->parent=y;//上面代码和红黑树右旋代码一样,下面两行代码用来维护附加信息size。 y->size=x->size; x->size=x->left->size+x->right->size+1; }
恢复插入引起的红黑树性质的破坏:
这代码和红黑树那一章的代码一样。
template<class Type>void orderStatisticTree<Type>::RBInsertFixup(node* currentNode){ while(currentNode->parent->color==RED){ if(currentNode->parent==currentNode->parent->parent->left){ node* uncleNode=currentNode->parent->parent->right; if(uncleNode->color==RED){ currentNode->parent->color=BLACK; uncleNode->color=BLACK; currentNode->parent->parent->color=RED; currentNode=currentNode->parent->parent; } else if(currentNode==currentNode->parent->right){ currentNode=currentNode->parent; leftRotate(currentNode); } else{ currentNode->parent->color=BLACK; currentNode->parent->parent->color=RED; rightRotate(currentNode->parent->parent); } } else { node* uncleNode=currentNode->parent->parent->left; if(uncleNode->color==RED){ currentNode->parent->color=BLACK; uncleNode->color=BLACK; currentNode->parent->parent->color=RED; currentNode=currentNode->parent->parent; } else if(currentNode==currentNode->parent->left){ currentNode=currentNode->parent; rightRotate(currentNode); } else{ currentNode->parent->color=BLACK; currentNode->parent->parent->color=RED; leftRotate(currentNode->parent->parent); } } } root->color=BLACK; }
插入:
template<class Type>void orderStatisticTree<Type>::insert(const Type& val){ node* currentNode=root; node* prevNode=nullNode; while(currentNode!=nullNode){ currentNode->size+=1;//从根到新插入点路径上的各个结点size加1。 prevNode=currentNode; if(val<currentNode->key) currentNode=currentNode->left; else currentNode=currentNode->right; } if(prevNode==nullNode) root=new node(val,1,nullNode,nullNode,nullNode,BLACK); else if(val<prevNode->key){ prevNode->left=new node(val,1,prevNode,nullNode,nullNode,RED); RBInsertFixup(prevNode->left); } else{ prevNode->right=new node(val,1,prevNode,nullNode,nullNode,RED); RBInsertFixup(prevNode->right); }}
恢复删除引起的红黑树性质的破坏:
template<class Type>void orderStatisticTree<Type>::RBRemoveFixup(node* currentNode){ node* tmp=currentNode->parent; while(tmp!=nullNode){ tmp->size=tmp->left->size+tmp->right->size+1; tmp=tmp->parent; }//将currentNode到根路径上的各个节点size减1。 while(currentNode!=root&¤tNode->color==BLACK){ if(currentNode==currentNode->parent->left){ node* brotherNode=currentNode->parent->right; if(brotherNode->color==RED){ brotherNode->color=BLACK; currentNode->parent->color=RED; leftRotate(currentNode->parent); } else if (brotherNode->left->color==BLACK&&brotherNode->right->color==BLACK){ brotherNode->color=RED; currentNode=currentNode->parent; } else if(brotherNode->right->color==BLACK){ brotherNode->left->color=RED; brotherNode->color=RED; rightRotate(brotherNode); brotherNode=currentNode->parent->right; } else{ brotherNode->color=currentNode->parent->color; currentNode->parent->color=BLACK; leftRotate(currentNode->parent); currentNode=root; } } else{ node* brotherNode=currentNode->parent->left; if(brotherNode->color==RED){ brotherNode->color=BLACK; currentNode->parent->color=RED; rightRotate(currentNode->parent); } else if (brotherNode->right->color==BLACK&&brotherNode->left->color==BLACK){ brotherNode->color=RED; currentNode=currentNode->parent; } else if(brotherNode->left->color==BLACK){ brotherNode->right->color=RED; brotherNode->color=RED; leftRotate(brotherNode); brotherNode=currentNode->parent->left; } else{ brotherNode->color=currentNode->parent->color; currentNode->parent->color=BLACK; rightRotate(currentNode->parent); currentNode=root; } } } currentNode->color=BLACK;}
删除:
代码和红黑树中删除代码一样。
template<class Type>void orderStatisticTree<Type>::transplant(node* u,node* v){ if(u->parent==nullNode) root=v; else if(u==u->parent->right) u->parent->right=v; else u->parent->left=v; v->parent=u->parent;}template<class Type>bool orderStatisticTree<Type>::remove(const Type& val){ node* searchNode=search(val,root); if(searchNode==nullNode) return false; int originalColor; node* x=0; if(searchNode->left==nullNode){ x=searchNode->right; transplant(searchNode,searchNode->right); originalColor=searchNode->color; } else if(searchNode->right==nullNode){ x=searchNode->left; transplant(searchNode,searchNode->left); originalColor=searchNode->color; } else{ node* succNode=findMinimum(searchNode->right); originalColor=succNode->color; x=succNode->right; if(succNode->parent==searchNode) x->parent=succNode; else{ transplant(succNode,succNode->right); succNode->right=searchNode->right; succNode->right->parent=succNode; } transplant(searchNode,succNode); succNode->left=searchNode->left; succNode->color=searchNode->color; succNode->size=searchNode->size; } delete searchNode; if(originalColor==BLACK) RBRemoveFixup(x); return true;}
查找第i小关键字:
//返回第i小的元素:template<class Type>const Type& orderStatisticTree<Type>::select(int i) const{ node* currentNode=root; int rank=currentNode->left->size+1; while(rank!=i){ if(i<rank) currentNode=currentNode->left; else{ currentNode=currentNode->right; i=i-rank; } rank=currentNode->left->size+1; } return currentNode->key;}
返回一个元素的秩:
template<class Type>int orderStatisticTree<Type>::rank(const Type& val) const{ node* searchNode=search(val,root); if(searchNode==nullNode) throw runtime_error("the element is not existent in the tree."); int rank=searchNode->left->size+1; node* currentNode=searchNode; while(currentNode!=root){ if(currentNode==currentNode->parent->right) rank+=currentNode->parent->left->size+1; currentNode=currentNode->parent; } return rank;}
0 0
- 第十四章 数据结构扩张 动态顺序统计部分代码
- 第十四章 数据结构的扩张
- 《算法导论》第14章 数据结构的扩张 (1)动态顺序统计
- 算法导论 第14章 数据结构的扩张(一)动态顺序统计树
- 算法导论第十四章:数据结构的扩张
- 算法导论第十四章数据结构的扩张
- 算法导论 第十四章:数据结构的扩张
- 数据结构-红黑树扩张-顺序统计树
- 第14章 数据结构扩张 区间树部分代码
- 算法导论 红黑树的扩张 动态顺序统计
- 算法导论学习笔记-第十四章-数据结构的扩张
- 数据结构的扩张(动态有序统计和区间树)笔记
- 算法导论代码 第14章 数据结构的扩张
- 算法导论第十四章利用红黑树查找顺序统计量
- 算法导论第十四章习题14.1-7利用顺序统计数统计数组中的逆序数
- 数据结构扩张
- 算法导论第十四章顺序统计量树确定一个元素的秩
- 算法导论 14章 数据结构的扩张
- Hive集成HBase(一)
- Asp.net 设置TextBox只能输入数字
- 我的第一次上机实验1-2 第二个项目
- Handlerl自我理解,望指正
- 学习笔记3.14--mongodb的安装和简单的使用
- 第十四章 数据结构扩张 动态顺序统计部分代码
- 全排列字符串java实现
- UVA - 10079 Pizza Cutting (直线划分平面问题,公式解决)
- allegro 自动批量创建device文件
- JAVA AOP实现方式
- 扒扒数据库长长知识(下载资源组合看)之 00(oracle简介)
- Java 内存模型及GC原理
- Android 开发中一些不得不知的坑(二)
- 排序总结(二)