Algorithm Series Note 5 (Extended data structure-dynamic sequential statistics and interval tree)

Source: Internet
Author: User

In programming, we tend to use existing data structures that do not solve the problem, it is not urgent to create a new data structure, but the existing data structures based on the addition of new fields. This section expands on the basic data structure of the last note red-black tree, and draws two important applications-dynamic sequential statistics and interval trees.

Dynamic Sequential Statistics

In the algorithm series Note 2 we completed the sequential statistics of the static table in linear time, and here we expand on the red and black tree, complete the operation in O (LGN) time, mainly including returning The elements of rank I Os_select (i) and given an element x, returns its rank (Os_rank (x)).

idea: Add a new item: Record the number of sub-trees on the node of the red and black tree. SIZE[X] = size[left[x]] + size[right[x]] +1. If the node is empty, it is 0.

In addition, when you insert and delete the data structure of the extension, you need to update the size of the subtree at any time, in sync with the INSERT and delete operations, but you need to re-bring it back to balance. Mainly in the Case2 and case3 of the two cases of rotation. < can be compared with the algorithm series note 4> red black tree Insert code to see the changes.

Code:

Returns the element Os_select (i) ranking

bstnode* Osrbtree::os_select (bstnode *p, const int &ith) {if (p = = NULL) return p;int k = 1;if (P->left! = null) {k = P ->left->size + 1;           The current node corresponds to the rank}if (ith = = k) return p;if (ith < K) return Os_select (p->left, ith); else return Os_select (P->right, ITH-K);}

Given an element x, return its rank (Os_rank (x))

  return the rank of Valueint Osrbtree::os_rank (Bstnode *p, const int &value) {if (p = = NULL) return 0;int k = 1;if (P->left! = NULL) K = p->left->size + 1;if (p->val = = value) return K;else if (P->val > value) return Os_ran K (p->left, value), Else return Os_rank (p->right, value) +k;}
Full code:

OSTree.h

#ifndef osrbtree#define osrbtree#include <iostream> #include <string>using namespace Std;class bstnode{ Public:bstnode *left, *right; Bstnode *parent;int val;string color;int size;}; Class Osrbtree{public:osrbtree (const int &rootval) {root = new Bstnode (); root->val = Rootval;root->left = NULL; Root->right = Null;root->color = "BLACK"; root->size = 1;root->parent = NULL;} bstnode* Insertbst (bstnode *p, const int &value), void Insertosrbtree (Bstnode *root1, const int &value); void Inord Erosrbtree (Bstnode *p); bstnode* Os_select (bstnode *p, const int &ith), int os_rank (Bstnode *p, const int &value);p ublic:bstnode *root;}; #endif
OSTree.cpp

#include "OSRBTree.h"//two fork find tree insert bstnode* osrbtree::insertbst (bstnode *p, const int &value) {Bstnode *y = NULL; Bstnode *in = new Bstnode () In->left = Null;in->right = Null;in->val = Value;in->parent = NULL;in->size = 1 ; while (P! = NULL) {y = p;p->size + = 1;if (P->val > In->val) p = p->left;else p = p->right;} if (y = = NULL) p = in;else{in->parent = Y;if (Y->val > In->val) y->left = In;else y->right = in;} return in;} Insert Red black tree void Osrbtree::insertosrbtree (Bstnode *root1, const int &value) {Bstnode * in = Insertbst (root1, value); In-&gt ; color = "Red"; while (in! = root1 && In->color = = "Red") {//adjust the red and black features if (In->parent->color = = "   Black ") return; It is guaranteed that the if (in->parent = = in->parent->parent->left) {Bstnode *y = in->parent->parent->right;if ( Y! = NULL && Y->color = = "Red") {//Case 1y->color = "BLACK"; y->parent->color = "Red"; in->parent ->color = "BLACK"; in = In->pareNt->parent;} Else{if (in = = In->parent->right) {//Case 2 in->parent l bstnode *pa = In->parent;in->size = pa->    Size Modify this node to include the number of subtree nodes in->parent = Pa->parent;pa->parent->left = In;pa->parent = In;if (pa->left! = NULL)        Pa->size = pa->left->size + 1; Modify knot subtree node size else Pa->size = 1;if (in->left! = NULL) {in->left->parent = pa;pa->size + = In->left->siz e;} Pa->right = In->left;in->left = Pa;in = PA;} Case 3 In->parent->parent Right Bstnode *pa = in->parent; Bstnode *gpa = In->parent->parent;pa->size = Gpa->size;if (gpa->parent! = NULL) {if (GPA = = gpa->parent- >left) {gpa->parent->left = PA;} Elsegpa->parent->right = PA;} Pa->parent = Gpa->parent;if (gpa->right! = NULL) Gpa->size = gpa->right->size + 1;else gpa->size = 1;i F (pa->right! = NULL) {gpa->size + = Pa->right->size;pa->right->parent = GPA;} Gpa->left = Pa->right;pa->right = Gpa;gpa->parent = Pa;pa->color = "BLACK"; gpa->color = "Red";}}  Else{bstnode *y = in->parent->parent->left;if (Y! = NULL && Y->color = = "Red") {//Case 1y->color = "BLACK"; y->parent->color = "red"; In->parent->color = "BLACK"; in = in->parent->parent;}   else{//Do the same as A and left and right swap if (in = = In->parent->left) {//Case 2    In->parent right-handed bstnode *pa = In->parent;in->size = pa->size; Modify this node to include the number of subtree nodes in->parent = pa->parent;pa->parent->right = In;pa->parent = In;if (pa->right! = NULL) Pa->size = pa->right->size + 1;else pa->size = 1;if (in->right! = NULL) {in->right->parent = Pa;pa-&gt ; size + = in->right->size;} Pa->left = In->right;in->right = Pa;in = PA;} Case 3 in->parent->parent L-bstnode *pa = in->parent; Bstnode *gpa = In->parent->parent;pa->size = Gpa->size;if (gpa->parent! = NULL) {if (GPA= = Gpa->parent->left) {gpa->parent->left = PA;} Elsegpa->parent->right = PA;} Pa->parent = Gpa->parent;if (gpa->left! = NULL) Gpa->size = Gpa->left->size+1;else Gpa->size = 1;if ( Pa->left = NULL) {pa->left->parent = gpa;gpa->size + = pa->left->size;} Gpa->right = Pa->left;pa->left = Gpa;gpa->parent = Pa;pa->color = "BLACK"; gpa->color = "Red";}}} Root1->color = "Black";} Middle sequence traversal output void Osrbtree::inorderosrbtree (Bstnode *p) {if (p = = null) return;if (p->left! = null) Inorderosrbtree (p-> left); cout << p->val << p->color << p->size << ""; if (p->right! = NULL) inorderosrbtre E (p->right);} Give ith smallest valuebstnode* osrbtree::os_select (bstnode *p, const int &ith) {if (p = = NULL) return p;int k = 1;i           F (p->left! = NULL) {k = p->left->size + 1; The current node corresponds to the rank}if (ith = = k) return p;if (ith < K) return Os_select (p->left, ith); else return Os_select (P->righT, ith-k);} Return the rank of Valueint Osrbtree::os_rank (Bstnode *p, const int &value) {if (p = = NULL) return 0;int k = 1;if (P- >left! = NULL) K = p->left->size + 1;if (p->val = = value) return K;else if (P->val > Value) return Os_rank (p ->left, value), Else return Os_rank (p->right, value) +k;}
Main.cpp

int a[10] = {5,4,6, 7,2,4, 1, 8, 5, 10};osrbtree OSBRT (a[0]); for (int i = 1; i < i++) Osbrt.insertosrbtree (osbrt.root , A[i]); cout << "Results of the middle sequence traversal:" << endl;osbrt.inorderosrbtree (osbrt.root); cout << endl;int ith = 6; Bstnode *rank = Osbrt.os_select (osbrt.root, ith); if (rank = = NULL) cout << "Rank" << ith << "does not exist!! << endl;cout << ranking << ith << ":" << rank->val << endl;int x = 6;cout << X << "ranking:"; cout << Osbrt.os_rank (osbrt.root, x) << Endl;

Result:


Their time complexity is O (LGN), because the height of the red black Tree is O (LGN).

Question: Why not use these node rankings directly as newly added items? The reason is that when you make changes to the tree at this point, maintaining the tree becomes very laborious.

Methodology: as <ostree- Sequential Statistics Tree >

1 : Select a basic data structure (red-black tree)

2 : Maintain some additional information in data statistics (sub- tree size )

3 : Verify that the information on this data structure is not affected by the modification operation (INSERT, delete---rotations)

4 : Creates a new operation. Assume that the new data is already stored, and then start using the information (Os_select, Os_rank).


Interval trees (Interval tree)

problem: save a series of intervals, such as time intervals. You need to query all the intervals in the collection, which overlap with a given interval?

We proceed according to the methodology mentioned above:

1: Select the red and black tree as the basic data structure, and the lower value of the interval (low) as the key value

2: Set the maximum value of the knot tree as the newly added item (m[x] = max{high[int[x]],m[left[x]], m[right[x]}).

3: Is it affected by operations such as insert deletion? , but in O (1) time can be adjusted to see the code.

4: A new operation that queries the collection for an interval that overlaps a given interval.

Code:

IntervalTree.h

#ifndef intervaltree#define intervaltree#include <iostream> #include <string>using namespace std;struct Datanode{int low;int High;}; Class Bstnode{public:bstnode *left, *right; Bstnode *parent;int Val;datanode d;string color;int m;         Maximum value};class intervaltree{public:intervaltree (const DataNode &d) {root = new Bstnode (); root->d = d;root-> color = "BLACK"; root->left = Null;root->right = Null;root->m = D.high;root->parent = Null;root->val = D.low ;} bstnode* Insertbst (Bstnode *p, const dataNode &d); void Insertintervaltree (Bstnode *root1, const dataNode &d); void Inorderosrbtree (Bstnode *p); bstnode* Intervalsearch (Bstnode *p, const dataNode &d);p ublic:bstnode *root;void destroybst (Bstnode *p);}; #endif
IntervalTree.cpp

#include "IntervalTree.h" using namespace std; bstnode* Intervaltree::insertbst (Bstnode *p, const DataNode &d) {Bstnode *y = NULL; Bstnode *in = new Bstnode (); in->left = Null;in->right = Null;in->val = D.low;in->parent = NULL;in->m = D.hi  Gh;in->d = D;while (P! = NULL) {y = p;if (p->m < in->m) P->m = in->m; The maximum value for the subtree node if (P->val > In->val) p = p->left;else p = p->right;} if (y = = NULL) p = in;else{in->parent = Y;if (Y->val > In->val) y->left = In;else y->right = in;} return in;} void Intervaltree::insertintervaltree (Bstnode *root1, const DataNode &d) {Bstnode * in = Insertbst (ROOT1, D);in-> color = "Red", while (in! = root1 && In->color = = "Red") {//adjust the red and black features if (In->parent->color = = "b   Lack ") return; It is guaranteed that the if (in->parent = = in->parent->parent->left) {Bstnode *y = in->parent->parent->right;if ( Y! = NULL && Y->color = = "Red") {//Case 1y->color = "BLACK"; y->pArent->color = "Red"; In->parent->color = "BLACK"; in = in->parent->parent;}    Else{if (in = = In->parent->right) {//Case 2 in->parent l bstnode *pa = In->parent;in->m = pa->m; Modify this node to include the number of subtree nodes in->parent = Pa->parent;pa->parent->left = In;pa->parent = In;if (pa->left! = NULL) P A->m = pa->left->m > pa->m? Pa->left->m:pa->m;if (In->left! = NULL) {in->left->parent = Pa;pa->m = in->left->m > pa-& Gt;m? Pa->left->m:pa->m;} Pa->right = In->left;in->left = Pa;in = PA;} Case 3 In->parent->parent Right Bstnode *pa = in->parent; Bstnode *gpa = In->parent->parent;pa->m = Gpa->m;if (gpa->parent! = NULL) {if (GPA = = gpa->parent-> left) {gpa->parent->left = PA;} Elsegpa->parent->right = PA;} Pa->parent = Gpa->parent;if (gpa->right! = NULL) gpa->m = gpa->right->m > gpa->m? Gpa->right->m:gpa->m;if (pa->right! = NULL) {gpa->m = pa->right->m > gpa->m? pa->right->m:gpa->m;pa->right->parent = GPA;} Gpa->left = Pa->right;pa->right = Gpa;gpa->parent = Pa;pa->color = "BLACK"; gpa->color = "Red";}}  Else{bstnode *y = in->parent->parent->left;if (Y! = NULL && Y->color = = "Red") {//Case 1y->color = "BLACK"; y->parent->color = "red"; In->parent->color = "BLACK"; in = in->parent->parent;}   else{//Do the same as A and left and right swap if (in = = In->parent->left) {//Case 2    In->parent right-handed bstnode *pa = In->parent;in->m = pa->m; Modify this node to include the number of subtree nodes in->parent = pa->parent;pa->parent->right = In;pa->parent = In;if (pa->right! = NULL) Pa->m = pa->right->m > pa->m? Pa->right->m:pa->m;if (in->right! = NULL) {in->right->parent = Pa;pa->m = in->right->m > Pa->m? In->right->m:pa->m;} Pa->left = In->right; in->right = Pa;in = PA;} Case 3 in->parent->parent L-bstnode *pa = in->parent; Bstnode *gpa = In->parent->parent;pa->m = Gpa->m;if (gpa->parent! = NULL) {if (GPA = = gpa->parent-> left) {gpa->parent->left = PA;} Elsegpa->parent->right = PA;} Pa->parent = Gpa->parent;if (gpa->left! = NULL) gpa->m = gpa->left->m > gpa->m? Gpa->left->m:gpa->m;if (Pa->left! = NULL) {pa->left->parent = Gpa;gpa->m = pa->left->m > Gpa->m? Pa->left->m:gpa->m;} Gpa->right = Pa->left;pa->left = Gpa;gpa->parent = Pa;pa->color = "BLACK"; gpa->color = "Red";}}} Root1->color = "Black";} void Intervaltree::inorderosrbtree (Bstnode *p) {if (p = = null) return;if (p->left! = null) Inorderosrbtree (p->left) ; cout << p->val << p->color << p->m << "";//cout << p->d.low << p->col or << p->d.high << ""; if (p->right! = NULL) InorderoSrbtree (p->right);} bstnode* Intervaltree::intervalsearch (Bstnode *p, const DataNode &d) {while (P! = NULL && (D.low > P->d.h IgH | | D.high < P->d.low) {if (P->left! = NULL && D.low < p->m) p = p->left;else p = p->right;} return p;} void Intervaltree::d estroybst (Bstnode *p) {if (p = = null) return;if (p->left! = null) {DESTROYBST (p->left);} if (p->right! = NULL) {destroybst (p->right);} Delete p;}
Main.cpp

int a[6] = {N, 5, 4, 8, 7};int b[6] = {0, one, one,,, 6, 10};vector<datanode> data;for + +) {DataNode D;d.low = a[i];d. High = B[i];d ata.push_back (d);} Intervaltree interval (data[0]); for (int i = 1; i < data.size (); i++) {Interval.insertintervaltree (Interval.root, data[ I]);} cout << "Results of the middle sequence traversal:" << endl;interval.inorderosrbtree (interval.root); cout << Endl;datanode sd;sd.low = 18;sd.high = 25; Bstnode * BST = Interval.intervalsearch (interval.root, SD) cout << "[" << bst->d.low << "," << Bst->d.high << "]" << Endl;

Result:


The time complexity is O (LGN), because the height of the red-black tree is O (LGN).

Algorithm Series Note 5 (Extended data structure-dynamic sequential statistics and interval tree)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.