算法导论 红黑树的扩张 动态顺序统计
来源:互联网 发布:淘宝聘用店主 编辑:程序博客网 时间:2024/06/10 04:51
#include <stdio.h> #include <stdlib.h> #define RED 1 #define BLACK 0 typedef struct RBTreeNode { int key; int color; int size; RBTreeNode *p; RBTreeNode *left; RBTreeNode *right; }RBT,*pRBT; pRBT nil=(pRBT)malloc(sizeof(RBT)); int bh=0; void initNil() { nil->key=-1; nil->color=BLACK; nil->p=NULL; nil->left=NULL; nil->right=NULL; nil->size=0;} void leftRotate(pRBT *root,pRBT x) { //左旋要有右子树 if(x->right==nil) return; pRBT y=x->right; x->right=y->left; if(y->left != nil) y->left->p=x; y->p=x->p; if(x->p==nil) { (*root)=y; } else if(x == x->p->left) { x->p->left=y; } else { x->p->right=y; } y->left=x; x->p=y; //维护子树数目y->size=x->size;x->size=x->left->size+x->right->size+1;} void rightRotate(pRBT *root,pRBT x) { //右旋要有左子树 if(x->left==nil) return; pRBT y=x->left; x->left=y->right;if(y->right != nil) y->right->p=x; y->p=x->p; if(x->p==nil) { (*root)=y; } else if(x==x->p->left) { x->p->left=y; } else { x->p->right=y; } y->right=x; x->p=y; //维护子树数目x->size=y->size;y->size=y->left->size+y->right->size+1;} void rbInsertFixup(pRBT *root,pRBT z) { while(z->p->color==RED) { if(z->p==z->p->p->left) { pRBT y=z->p->p->right; if(y->color==RED) { z->p->color=BLACK; y->color=BLACK; z->p->p->color=RED; z=z->p->p; } else { if(z==z->p->right) { z=z->p; leftRotate(root,z); } z->p->color=BLACK; z->p->p->color=RED; rightRotate(root,z->p->p); } } else { pRBT y=z->p->p->left; if(y->color==RED) { z->p->color=BLACK; y->color=BLACK; z->p->p->color=RED; z=z->p->p; } else { if(z==z->p->left) { z=z->p; rightRotate(root,z); } z->p->color=BLACK; z->p->p->color=RED; leftRotate(root,z->p->p); } } } if((*root)==nil || (*root)->color==RED) bh++; (*root)->color=BLACK; } void rbInsert(pRBT *root,int key) { pRBT z=(pRBT)malloc(sizeof(RBT)); z->key=key;z->size=1; pRBT x=(*root); pRBT y=nil; while(x != nil) { x->size++;//从根下降过程中,增加路径上所有子树数目 y=x; if(z->key<x->key) { x=x->left; } else { x=x->right; } } z->p=y; if(y==nil) { (*root)=z; } else if(z->key<y->key) { y->left=z; } else { y->right=z; } z->left=nil; z->right=nil; z->color=RED; rbInsertFixup(root,z); } void rbTransplant(pRBT *root,pRBT u,pRBT v) { if(u->p==nil) (*root)=v; else if(u==u->p->left) u->p->left=v; else u->p->right=v; v->p=u->p; } pRBT treeMinimum(pRBT root) { if(root==nil) return root; pRBT x=root; while(x->left!=nil) { x=x->left; } return x; } void rbDeleteFixup(pRBT *root,pRBT x) { while(x != *root && x->color==BLACK) { if(x==x->p->left) { pRBT w=x->p->right; if(w->color==RED) { w->color=BLACK; x->p->color=RED; leftRotate(root,x->p); w=x->p->right; } if(w->left->color==BLACK && w->right->color==BLACK) { w->color=RED; x=x->p; if(x==*root)bh--; } else { if(w->right->color == BLACK) { w->left->color=BLACK; w->color=RED; rightRotate(root,w); w=x->p->right; } w->color=x->p->color; x->p->color=BLACK; w->right->color=BLACK; leftRotate(root,x->p); x=(*root); } } else { pRBT w=x->p->left; if(w->color==RED) { w->color=BLACK; x->p->color=RED; rightRotate(root,x->p); w=x->p->left; } if(w->left->color==BLACK && w->right->color==BLACK) { w->color=RED; x=x->p; } else { if(w->left->color == BLACK) { w->right->color=BLACK; w->color=RED; leftRotate(root,w); w=x->p->left; } w->color=x->p->color; x->p->color=BLACK; w->left->color=BLACK; rightRotate(root,x->p); x=(*root); } } } x->color=BLACK; } void rbDelete(pRBT *root,pRBT z) { pRBT y=z->p,x;//新增一段回溯到根的迭代,减少路径上每个结点的子树数目while(y){y->size--;y=y->p;} y=z; int yOrigColor=y->color; if(z->left==nil) { x=z->right; rbTransplant(root,z,x); } else if(z->right==nil) { x=z->left; rbTransplant(root,z,x); } else { y=treeMinimum(z->right); yOrigColor=y->color; x=y->right; if(y->p==z) { x->p=y; } else { rbTransplant(root,y,x); y->right=z->right; y->right->p=y; } rbTransplant(root,z,y); y->left=z->left; y->left->p=y; y->color=z->color; if(yOrigColor==BLACK) rbDeleteFixup(root,x); } } void preTrav(pRBT root,char c) { if(root==nil) return; else { printf("%d ",root->key); if(root->color==BLACK) printf("%s ","黑"); else printf("%s ","红"); printf("%c ",c); preTrav(root->left,'L'); preTrav(root->right,'R'); } } pRBT treeSearch(pRBT root,int key) { pRBT x=root; while(x!=nil && x->key!=key) { if(key<x->key) x=x->left; else x=x->right; } return x; } pRBT at(pRBT root,int i){if(root==nil)return nil;pRBT x=root;int r=x->left->size+1;if(i==r)return x;else if(i<r)return at(x->left,i);elsereturn at(x->right,i-r);}int getIndex(pRBT root,pRBT x){int r=x->left->size+1;pRBT y=x;while(y != root){if(y==y->p->right)r=r+y->p->left->size+1;y=y->p;}return r;} void main() { initNil(); pRBT root=nil; rbInsert(&root,100); rbInsert(&root,80); rbInsert(&root,90); rbInsert(&root,70); rbInsert(&root,10); rbInsert(&root,20); rbInsert(&root,30); rbInsert(&root,50); rbInsert(&root,60); rbInsert(&root,40); pRBT x=at(root,3);printf("%d\n",x->key);int r=getIndex(root,x);printf("%d\n",r); getchar(); }
阅读全文
0 0
- 算法导论 红黑树的扩张 动态顺序统计
- 《算法导论》第14章 数据结构的扩张 (1)动态顺序统计
- 算法导论 第14章 数据结构的扩张(一)动态顺序统计树
- 算法导论动态表扩张
- 算法导论程序33--动态顺序统计
- 算法导论-数据结构的扩张
- 【算法导论-34】红黑树、顺序统计树的Java实现
- 算法导论 第14章 14.1 动态顺序统计
- 《算法导论》笔记 第14章 14.1 动态顺序统计
- 算法导论--动态顺序统计与区间树
- 算法导论14.1动态顺序统计 练习总结
- 算法导论 动态顺序统计与区间树
- 算法导论 ch14 数据结构的扩张
- 算法导论第十四章:数据结构的扩张
- 算法导论第十四章数据结构的扩张
- 算法导论笔记:14数据结构的扩张
- 算法导论 14章 数据结构的扩张
- 算法导论 14章 数据结构的扩张
- 加解密
- java实现循环单链表
- 闭包详解
- c# 弹出窗体选择文件代码
- android:screenOrientation属性
- 算法导论 红黑树的扩张 动态顺序统计
- iscsi简介和配置
- 操作符/控制执行流程/初始化与清理
- 关于机器学习比较好的几个网站
- USB驱动程序(一)————USB主机控制器驱动——OHCI分析
- 配置背景色
- (37)网格物体Actor
- 音视频聊天开发: 7 Android下ffmpeg+x264编译
- Spring中加载外部资源文件的几种方式