數據結構-數據結構的擴展
阿新 • • 發佈:2018-03-28
item 之前 pan repl 維護 mark focus == pla
4個步驟:
-
選擇一種基礎數據結構
-
確定基礎數據結構中要維護的附加信息
-
檢查基礎數據結構上一些操作是否需要維護附加信息
-
為附加信息添加一些新的操作
2 舉例
擴展紅黑樹(或是其他樹),能夠在O(lgn)內獲取第i小的元素.
RBNode* RBTree::find(size_t i) { return axu_find(mp_root,i); } RBNode* RBTree::aux_find(RBNode* cur,size_t i) { size_t index = cur->left->size+1;//當前節點在書中的序號,秩 if(index==i) { return cur; }else if(index < i){ //i還有在 cur 的後面 return aux_find(cur->right,i-r);// i-r 表示,之前已經有r個了,再往後找i-r個就是了 }else if(index > i){ // i 在 cur 的前面 return aux_find(cur->left); // 沒有跳過任何元素,因此直接傳 i } }
size_t* RBTree::find(RBNode *node) { size_t index = node->left->size+1; // 這只是自己統治下節點的排序. RBNode* pre = node; while(pre != mp_root) { //只有自己是一個右節點的時候,才要加上左節點的元素數目,如果不是,就不加. if(pre == pre->p->right) { r=r+pre->p->left->size+1; //自己父節點的右子樹個數 + 父節點的1 } pre = pre->p; //向上遞歸,直到p是根節點. } }
-
添加元素時,所有元素途徑的路徑上
size+1
,添加以後,自己的size=1
,O(lgn) -
旋轉,以左旋為例: 原先父節點pre,旋轉以後父節點cur
新的父節點的size等於原先父節點的size.(因為元素個數沒變)
原先父節點的個數變為
pre->size=pre->left->size+cur->right->size+1
刪除過程:
-
刪除操作,遍歷路徑從根節點到節點
replace_node
,路徑上所有節點size-1
-
旋轉,同插入
數據結構-數據結構的擴展