Introduction to algorithm-14.3-6-min-gap

Source: Internet
Author: User
I. Question

Describes how to maintain a dynamic dataset Q that supports an operational MIN-GAP so that this operation gives the minimum difference between two numbers in Q. For example, if q = {, 9, 15, 18, 22}, then the MIN-GAP (q) returns 18-15 = 3 because 15 and 18 are the last two of them. Use the insert, delete, search, and MIN-GAP operations to be as efficient as possible and analyze their runtime.


Ii. Thinking

Step 1: Basic Data Structure

The red/black tree. The values in the array are the keywords of each node.

Step 2: add information

Min-gap [x]: records the Min-gap of the tree with X as the root node. When X is the leaf node, Min-gap [x] = 0x7fffffff

Min-Val [x]: records the smallest keyword in the tree with X as the root node.

Max-Val [x]: records the largest keyword in the tree with X as the root node.

Step 3: maintain information

The added information is updated at the same time as the inserted deletion. the time complexity remains unchanged.


Step 4: design new operations

Min_gap (): returns the Min-gap value of the root node.

 

Iii. Code
# Include <iostream> using namespace STD; # define black 0 # define Red 1 // MIN-GAP Tree node Structure struct node {node * left; // left child node * right; // right-child node * P; // parent int key; // keyword bool color; // color, red or black int min_gap; // records the Min-gap of the tree with X as the root node. When X is the leaf node, Min-gap [x] = 0x7fffffint min_val; // records the smallest keyword int max_val in the tree with X as the root node; // record the largest keyword node (node * init, int K) in the tree with X as the root node: Left (init), right (init), P (init ), key (K), color (black), min_gap (0x7fffff), min_val (K), max_val (k) {}}; // struct min_gap_tree {node * root; // root node * nil; // sentinel min_gap_tree () {nil = new node (null,-1); root = nil ;};}; int min (int, int B, int C, int d) {A = A <B? A: B; C = C <D? C: D; return a <C? A: C;} // information maintenance void maintaining (min_gap_tree * t, node * X) {While (X! = T-> nil) {// maintenance of min_val information X-> min_val = (X-> left! = T-> nil )? X-> left-> min_val: X-> key; // maintenance of max_val information X-> max_val = (X-> right! = T-> nil )? X-> right-> max_val: X-> key; // maintenance of min_gap information int A = (X-> left! = T-> nil )? X-> left-> min_gap: 0x7fffffff; int B = (X-> right! = T-> nil )? X-> right-> min_gap: 0x7fffffff; int c = (X-> left! = T-> nil )? (X-> key-X-> left-> max_val): 0x7fffffff; int d = (X-> right! = T-> nil )? (X-> right-> min_val-X-> key): 0x7fffffff; X-> min_gap = min (A, B, C, D ); // update x = x-> P ;}// left-hand, so that Y = x-> right, left-hand rotation is based on the chain between x and y. // The involved nodes include: X, Y, Y-> left, so that node = {P, L, r }, the specific changes are as follows: // X = {X-> P, X-> left, y} is changed to {Y, X-> left, y-> left} // y = {X, Y-> left, Y-> right} is changed to {X-> P, X, y-> right} // y-> left = {Y, Y-> left, Y-> left-> right} is changed to {X, y-> left, Y-> left-> right} void left_rotate (min_gap_tree * t, node * X) {// make y = x-> rightnode * Y = x-> Right; // modify the pointer of the three nodes according to the preceding method. Note that the pointer order X-> right = Y-> left; If (Y-> left! = T-> nil) Y-> left-> P = x; y-> P = x-> P; If (X-> P = T-> nil) // special case: X is the root node T-> root = y; else if (x = x-> P-> left) x-> P-> left = y; else X-> P-> right = y; y-> left = x; X-> P = y; maintaining (t, x);} // right-hand, take y = x-> left, and the left-hand side is the axis of the chain between x and y. // The rotation process is similar to void right_rotate (min_gap_tree * t, node * X) {node * Y = x-> left; X-> left = Y-> right; if (Y-> right! = T-> nil) Y-> right-> P = x; y-> P = x-> P; If (X-> P = T-> nil) t-> root = y; else if (x = x-> P-> right) x-> P-> right = y; else X-> P-> left = y; y-> right = x; X-> P = y; maintaining (t, x );} // adjust void mg_insert_fixup (min_gap_tree * t, node * z) {node * Y; // The only situation that needs to be adjusted is the violation of nature 2, if there is no violation of nature 2, adjust the end while (Z-> P-> color = red) {// P [Z] is the left child, in three cases, if (Z-> P = z-> P-> left) {// make y the primary node of z y = z-> P-> right; // In the first case, z's uncle y is red if (Y-> color = red) {// Black P [Z] and y to solve the problem that both Z and P [Z] are red Z-> P-> color = black; y-> color = black; // place P [p [Z] in red to keep the property 5z-> P-> color = Red; // use P [p [Z] as the newly added node Z to repeat the while loop z = z-> P;} else {// The second case: z's uncle is black, and Z is the right child if (Z = z-> P-> right) {// to P [Z] left, in the third case, Z = z-> P; left_rotate (T, Z);} // In the third case, Uncle Z is black, and Z is the color of the left child // swap P [Z] and P [p [Z], and right-hand Z-> P-> color = black; z-> P-> color = Red; right_rotate (T, Z-> P) ;}// P [Z] is the right child, there are three cases, similar to the above else if (Z-> P = z-> P-> right) {Y = z-> P-> left; If (Y-> color = red) {z-> P-> color = black; y-> color = black; Z-> P-> color = Red; z = z-> P;} else {If (Z = z-> P-> left) {z = z-> P; right_rotate (t, z);} Z-> P-> color = black; Z-> P-> color = Red; left_rotate (t, z-> P) ;}}// set the root node to black T-> root-> color = black ;} // insert a node void min_gap_insert (min_gap_tree * t, node * z) {node * Y = T-> nil, * x = T-> root; // locate the position to be inserted, which is the same as that of the binary search tree while (X! = T-> nil) {Y = x; If (Z-> key <X-> key) x = x-> left; elsex = x-> right ;} z-> P = y; If (y = T-> nil) T-> root = z; else if (Z-> key <Y-> key) y-> left = z; Elsey-> right = z; Z-> left = T-> nil; Z-> right = T-> nil; // convert the newly inserted node into red Z-> color = Red; // start from the newly inserted node and adjust mg_insert_fixup (T, Z) up ); // maintain the Information maintaining (T, Z);} // adjust the tree. X points to a red/Black node, the adjustment process is to move the extra black along the tree void mg_delete_fixup (min_gap_tree * t, node * X) {node * W; // If the extra black is on a root node or a red node, the node will suck Black to become a black node while (X! = T-> root & X-> color = black) {// If X is the left node of its parent node (which corresponds to the right node) if (x = x-> P-> left) {// Let W be the brother of X, depending on W, there are three cases: // before the delete operation is executed, X will certainly have no brothers. After the delete operation is executed, X will certainly have brothers W = x-> P-> right; // first case: W is the red if (W-> color = red) {// change the color of W and P [x] W-> color = black; x-> P-> color = Red; // perform a left-handed left_rotate (t, x-> P) on P [X ); // new brother w = x-> P-> right for w x; // converts it to one of the three situations} // Case 2: W is black, both children of W are black if (W-> left-> color = Black & W-> right-> color = black) {// remove the Black W and X. // w only A black layer is removed to red, and X has an extra black layer. after removal, the original color w-> color = Red is restored; // Add a black X = x-> P on P [X]; // The New X has an extra black color, transfer to for loop continue processing} // The third case, W is black, W-> left is red, w-> right is a black else {If (W-> right-> color = black) {// change the color of W and left [x] W-> left-> color = black; W-> color = Red; // perform a right-hand right_rotate (t, w); // The new brother w whose W is X = x-> P-> right; // Changes to the fourth case at this time} // The fourth case: W is black, W-> left is black, w-> right is red. // modify the color of W and P [x] W-> color = x-> P-> color; x-> P-> color = black; W-> right-> color = Black; // perform a left-handed left_rotate (t, x-> P) on P [X]; // The adjustment is completed, set X as the root node to end the loop x = T-> root;} // If X is the left node of its parent node (the right node corresponds) else if (x = x-> P-> right) {// Let W be the X brother, depending on W, there are three cases: // before the delete operation is executed, X certainly has no brothers. After the delete operation is executed, X must have a sibling W = x-> P-> left; // first case: W is the red if (W-> color = red) {// change the color of W and P [x] W-> color = black; x-> P-> color = Red; // perform a left-hand right_rotate (t, x-> P) on P [X ); // new brothers W whose W is x w = x-> P-> left; // convert to one of the three situations} // Case 2: W is black, both children of W are black if (W-> right-> color = Black & W-> left-> color = black) {// remove the black color of W and X. // W has only one black layer, and the color turns red, X has an extra black layer. Remove the layer and restore the original color w-> color = Red; // Add a black layer x = x-> P on P [x; // now there is an extra black on the new X, which is transferred to the for loop for further processing} // In the third case, W is black, W-> right is red, w-> left is a black else {If (W-> left-> color = black) {// change the color of W and right [x] W-> right-> color = black; W-> color = Red; // perform a right-hand left_rotate (t, w); // The new brother w whose W is X = x-> P-> left; // Changes to the fourth case at this time} // The fourth case: W is black, W-> right is black, W-> left is red // modify the color of W and P [x] W-> color = X-> P-> color; X-> P-> color = black; W-> left-> color = black; // perform a left-hand right_rotate (t, x-> P) on P [X]; // The adjustment has ended, set X as the root node to end the loop x = T-> root ;}}// absorbs extra black X-> color = black ;} // find the minimum node * tree_minimum (min_gap_tree * t, node * X) {// if there is a node smaller than the current node while (X-> left! = T-> nil) x = x-> left; return X;} // search for the successor of the x node in the middle sequence, the successor is the smallest node * tree_successor (min_gap_tree * t, node * X) greater than key [x] {// if there is a right child if (X-> right! = T-> nil) // return tree_minimum (t, x-> right) at the minimum value in the right subtree; // if the right subtree of X is empty and X has a successor y, then Y is the lowest ancestor node of X, and the left son of Y is also node * Y = x-> P; while (y! = NULL & X = Y-> right) {x = y; y = Y-> P;} return y ;} // delete node * min_gap_delete (min_gap_tree * t, node * z) in the red/black tree {// locate and delete the node, this part is the same as deleting the Binary Search Tree node ** X, * Y; if (Z-> left = T-> nil | Z-> right = T-> nil) y = z; else y = tree_successor (T, Z ); if (Y-> left! = T-> nil) x = Y-> left; else x = Y-> right; X-> P = Y-> P; if (Y-> P = T-> nil) T-> root = x; else if (y = Y-> P-> left) y-> P-> left = x; Elsey-> P-> right = x; // maintenance of Information maintaining (t, x); If (y! = Z) {z-> key = Y-> key; // maintenance of Information maintaining (T, Z);} // If the deleted node is black, then you need to adjust if (Y-> color = black) mg_delete_fixup (t, x); Return y;} // recursively query the Binary Search Tree node * min_gap_search (node * X, int K) {// The leaf node is not found yet, or the current node is the searched node if (X-> key =-1 | K = x-> key) return X; // The searched node is located in the left subtree of the current node if (k <X-> key) return min_gap_search (X-> left, k ); // The searched node is located in the left subtree else return min_gap_search (X-> right, K) of the current node;} void print (node * X) {If (X-> key =-1) return; print (X-> left ); cout <X-> key <''<X-> color <Endl; print (X-> right);} int min_gap (node * r) {return r-> min_gap;} void print (min_gap_tree * t) {print (t-> root); cout <Endl;} int main () {// generate a MIN-GAP tree min_gap_tree * t = new min_gap_tree; int X; char ch; while (1) {cout <"enter an operation:" <Endl; cout <"I: Insert a random number to the set" <Endl; cout <"d x: delete a number with a value of X from the set" <Endl; cin> CH; Switch (CH) {// insert a keyword case 'I': {// generate a random number to be inserted x = rand () % 100; // display the number of just inserted cout <"the inserted number is" <x <Endl; node * z = new node (t-> nil, X ); min_gap_insert (T, Z); // output Min-gapcout <"Min-Gap =" <min_gap (t-> root) <Endl; break ;} // delete a keyword case 'D': {// enter the number of cells to be deleted. Cin> X; // first, find the number of node * ret = min_gap_search (t-> root, x) with the value of X from the set; // Delete the number in the set, if (ret = T-> nil) cout <"not exist" <Endl; elsemin_gap_delete (T, RET ); // output Min-gapcout <"Min-Gap =" <min_gap (t-> root) <Endl; break ;}} cout <Endl ;} return 0 ;}
Iv. Test code

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.