Introduction to algorithms-14-2-joseph's arrangement

Source: Internet
Author: User

Question:

The definition of the Joseph's problem is as follows: Suppose n people are arranged in a ring and there is a positive integer m <= n. Starting from a specific person, the number of records along the ring will be listed for every m person and the number of records will continue. This process continues until everyone is listed. The order of columns for each person defines the (n, m)-Joseph arrangement of integers 1, 2,... and N. For example, ()-Joseph PHUs is arranged as <, 4>.
A) suppose M is an integer. Describe an O (n) Time Algorithm to arrange the output (n, m)-Joseph for the given integer n.
B) suppose M is not a constant. Describe an O (nlgn) Time Algorithm to arrange the given integers n and M, and output (n, m)-Joseph.


Thoughts:

Based on the dynamic sequence statistics in 14.1, assume that the first point in the remaining vertex is deleted (0 at the initial time), and T points are left, the next vertex to be deleted is the (start + m-1) % t vertex of the remaining vertex.

Step 1: Basic Data Structure

Red/black tree

Step 2: add information

Size [x]: The number of (internal) knots (including X itself) of the subtree rooted in X, that is, the size of the subtree. Size [nil [T] = 0

Step 3: maintain information

Size [x] = size [left [x] + size [right [x] + 1

Insert operation: Update O (lgn) from the insert node to the root node)

Rotation operation: only two vertices O (1) on the rotating axis need to be updated)

Delete operation: Update O (lgn) from the parent node of the deleted node to the root node)

Code:

# Include <iostream> using namespace STD; # define black 0 # define Red 1 // structure of the red/black tree node struct node {// structure of the red/black tree node * left; node * right; node * parent; int key; bool color; int size; // number of (internal) knots (including X itself) of the Child tree rooted in X ), node (node * init, int K): Left (init), right (init), parent (init), key (K), color (black ), size (1) {}}; // ordered statistic tree structure struct OS _tree {node * root; // root node * nil; // sensen OS _tree () {nil = new node (null,-1); nil-> size = 0; root = nil ;}; }; // Maintenance of additional information void maintaining (node * X) {While (X-> key> = 0) {X-> size = x-> left-> size + X-> right-> size + 1; X = x-> parent ;}// left-hand, y = x-> right. The left-hand side is the pivot of the chain between x and y. // The involved nodes include X, Y, Y-> left, change node = {P, L, r} as follows: // X = {X-> parent, X-> left, y} to {y, x-> left, Y-> left} // y = {X, Y-> left, Y-> right} is changed to {X-> parent, X, y-> right} // y-> left = {Y, Y-> left, Y-> left-> right} is changed to {X, y-> left, Y-> left-> right} void left_rotate (OS _tree * t, n Ode * X) {// make y = x-> rightnode * Y = x-> right; // modify the pointers of the three nodes in the preceding way, note that the order of the pointer X-> right = Y-> left; If (Y-> left! = T-> nil) Y-> left-> parent = x; y-> parent = x-> parent; If (X-> parent = T-> nil) // special case: X is the root node T-> root = y; else if (x = x-> parent-> left) x-> parent-> left = y; else X-> parent-> right = y; y-> left = x; X-> parent = y; // maintenance of additional information y-> size = x-> size; x-> size = x-> left-> size + X-> right-> size + 1;} // right-hand, y = x-> left, left-hand rotation is based on the chain between x and y. // The rotation process is similar to void right_rotate (OS _tree * t, node * X) {node * Y = x-> left; x-> left = Y-> right; if (Y -> Right! = T-> nil) Y-> right-> parent = x; y-> parent = x-> parent; If (X-> parent = T-> nil) t-> root = y; else if (x = x-> parent-> right) x-> parent-> right = y; else X-> parent-> left = y; y-> right = x; X-> parent = y; // maintenance of additional information y-> size = x-> size; x-> size = x-> left-> size + X-> right-> size + 1;} // adjust void OS _tree_insert_fixup (OS _tree * t, node * z) {node * Y; // The only condition that needs to be adjusted. This is the violation of nature 2. If it does not violate nature 2, adjust the end while (Z-> parent-> color = red) {// parent [Z] When the left child, there are three conditions if (Z-> parent = z-> parent-> left) {// set Y to the Z node y = z-> parent-> right; // In the first case, z's uncle y is red if (Y-> color = red) {// black both parent [Z] and y to solve the problem that both Z and parent [Z] are red Z-> parent-> color = black; y-> color = black; // place parent [Parent [Z] in red to keep the property 5z-> parent-> color = Red; // use parent [Parent [Z] as the newly added node Z to repeat the while loop z = z-> parent;} else {// The second case: z's uncle is black, and Z is the right child if (Z = z-> parent-> right) {// for parent [Z] Left-handed, to the third case z = z-> parent; left_rotate (T, Z);} // third case: Z's uncle is black, and Z is the color of the left child // swap parent [Z] and parent [Parent [Z], and right-hand Z-> parent-> color = black; z-> parent-> color = Red; right_rotate (T, Z-> parent) ;}// when parent [Z] is the right child, there are three cases, similar to the above else if (Z-> parent = z-> parent-> right) {Y = z-> parent-> left; If (Y-> color = red) {z-> parent-> color = black; y-> color = black; Z-> parent-> color = Red; Z = z-> Parent-> parent;} else {If (Z = z-> parent-> left) {z = z-> parent; right_rotate (T, Z );} z-> parent-> color = black; Z-> parent-> color = Red; left_rotate (T, Z-> parent );}}} // set the root node to black T-> root-> color = black;} // insert a node void OS _tree_insert (OS _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; else if (Z-> key> X-> key) x = x-> right;} Z-> parent = 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 OS _tree_insert_fixup (T, Z); maintaining (z) ;}// adjust the tree. X points to a red/Black node, the adjustment process is to move the extra black along the tree void OS _tree_delete_fixup (OS _tree * t, node * X) {node * w; // if this extra black Color on a root node or a red knot, the node will absorb extra black and 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-> parent-> left) {// Let W be the X brother, 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-> parent-> right; // first case: W is the red if (W-> color = red) {// change the color of W and parent [x] W-> color = black; x-> parent-> color = Red; // perform a left-handed left_rotate (t, x-> parent) operation on the parent [x ); // new brother w = x-> parent-> 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-> rig Ht-> color = black) {// remove the Black W and X. // w only has one black layer. Remove the black layer and change it to Red. X has an extra black layer, remove and restore the original color w-> color = Red; // Add a black X = x-> parent on the parent [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-> 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); // set w to X's new brother w = x-> parent-> right; // This is the fourth case} // The fourth case: W is black, W-> left is black, W-> right is red // modify the color of W and parent [x] W-> Co Lor = x-> parent-> color; X-> parent-> color = black; W-> right-> color = black; // perform a left-handed left_rotate (t, x-> parent) operation on the parent [X]; // The adjustment has ended, 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-> parent-> right) {// the brother who makes w x different from 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-> parent-> left; // first case: W is the red if (W-> color = red) {// change the color of W and parent [x] W-> color = black; x-> parent-> color = Red; // perform a left-handed righ operation on the parent [X ]. T_rotate (t, x-> parent); // set w to X's new brother w = x-> parent-> left; // convert to one of the three situations} // The second case: 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 only has a black color, which turns red. X has an extra black color, and then restores the original color w-> color = Red; // Add a black X = x-> parent on the parent [X]; // now the new x has an extra black, transfer to for loop continue processing} // 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; // Rows: Right-handed left_rotate (T, W); // new brother w whose W is X = x-> parent-> left; // This is the fourth case} // The fourth case: W is black, W-> right is black, w-> left is red. // modify the color of W and parent [x] W-> color = x-> parent-> color; x-> parent-> color = black; W-> left-> color = black; // perform a left-hand right_rotate (t, x-> parent) operation on the parent [x ); // now the adjustment has ended. set X as the root node to end the cycle x = T-> root ;}}} // absorbed extra black X-> color = black;} // find the minimum node * OS _tree_minimum (OS _tree * t, node * X) {// as long as 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, followed by the smallest node * OS _tree_successor (OS _tree * t, node * X) greater than key [x] {// if there is a right child if (X-> right! = T-> nil) // return OS _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 next y, then Y is the lowest ancestor node of X, and the left son of Y is also node * Y = x-> parent; while (y! = NULL & X = Y-> right) {x = y; y = Y-> parent;} return y ;} // recursively query the Binary Search Tree node * OS _tree_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 OS _tree_search (X-> left, k ); // The searched node is located in the left subtree else return OS _tree_search (X-> right, K) of the current node;} // delete node * OS _tree_delete (OS _tree * t, node * z) {// locate the node and delete it. This part is the same as the delete node * X of the Binary Search Tree, * Y; If (Z-> left = T-> nil | Z-> right = T-> nil) y = z; else y = OS _tree_successor (t, z); If (Y-> left! = T-> nil) x = Y-> left; else x = Y-> right; X-> parent = Y-> parent; if (Y-> parent = T-> nil) T-> root = x; else if (y = Y-> parent-> left) y-> parent-> left = x; Elsey-> parent-> right = x; maintaining (Y-> parent); If (y! = Z) {z-> key = Y-> key; maintaining (z) ;}// if the deleted node is black, you need to adjust if (Y-> color = black) OS _tree_delete_fixup (t, x); Return y ;} // find the I-largest node in the tree with X as the root node * OS _tree_select (node * X, int I) {// set the number of dots in the left subtree of X as the R-1, int r = x-> left-> size + 1; // If (r = I) return X, X is the largest node in the X Tree; // The element larger than I is in X-> left else if (I <r) return OS _tree_select (X-> left, I ); // The element larger than I is in X-> right else return OS _tree_select (X-> right, I-r);} int main () {// generate a dynamic sequence statistics tree OS _tree * t = new OS _tree; int m, n, I; while (CIN> N> m) {// set 1 ., N is inserted into the tree sequentially for (I = 1; I <= N; I ++) {node * z = new node (t-> nil, I ); OS _tree_insert (T, Z);} int t = n, start = 0; // There are still remaining nodes while (t) {// calculate the position of the next node to be deleted in the remaining node start = (start + m-1) % T; // find this node * ret = OS _tree_select (t-> root, start + 1); cout <ret-> key <''; // Delete this node OS _tree_delete (T, RET); t --;} cout <Endl;} return 0 ;}

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.