{"id":608,"date":"2013-05-30T14:58:16","date_gmt":"2013-05-30T13:58:16","guid":{"rendered":"http:\/\/oprsteny.cz\/?p=608"},"modified":"2015-02-27T14:54:25","modified_gmt":"2015-02-27T13:54:25","slug":"algorithms-in-place-algorithm-to-rearrange-elements-of-an-array","status":"publish","type":"post","link":"https:\/\/oprsteny.cz\/?p=608","title":{"rendered":"Algorithms: In-place algorithm to rearrange elements of an array"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"610\" data-permalink=\"https:\/\/oprsteny.cz\/?attachment_id=610\" data-orig-file=\"https:\/\/oprsteny.cz\/wp-content\/uploads\/C++.png\" data-orig-size=\"50,50\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"C++\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/oprsteny.cz\/wp-content\/uploads\/C++.png\" class=\"alignleft size-full wp-image-610\" src=\"http:\/\/oprsteny.cz\/wp-content\/uploads\/C++.png\" alt=\"C++\" width=\"50\" height=\"50\" \/>In a given array of elements like<code><br \/>\n[a<sub>1<\/sub>, a<sub>2<\/sub>, ..., a<sub>n<\/sub>, b<sub>1<\/sub>, b<sub>2<\/sub>, ..., b<sub>n<\/sub>, &lt;X&gt;<sub>1<\/sub>,&lt;X&gt;<sub>2<\/sub>, ..., &lt;X&gt;<sub>n<\/sub>]<\/code><br \/>\nwithout taking a extra memory swap elements in the array so the outcome will be like<br \/>\n<span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">[a<\/span><sub style=\"font-style: normal;\">1<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">, b<\/span><sub style=\"font-style: normal;\">1<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">, &#8230; &lt;X&gt;<\/span><sub style=\"font-style: normal;\">1<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">, a<\/span><sub style=\"font-style: normal;\">2<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">, b<\/span><sub style=\"font-style: normal;\">2<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">, &#8230; &lt;X&gt;<\/span><sub style=\"font-style: normal;\">2<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">, &#8230;, a<\/span><sub style=\"font-style: normal;\">n<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">, b<\/span><sub style=\"font-style: normal;\">n<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">, &#8230;, &lt;X&gt;<\/span><sub style=\"font-style: normal;\">n<\/sub><span style=\"font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace; font-size: 13px; font-style: normal; line-height: normal;\">]<!--more--><\/span><\/p>\n<h1>Solution 1<\/h1>\n<ol>\n<li>Prepare an array with X groups with N elements.<\/li>\n<li>Process first two groups\n<ol>\n<li>Divide these groups into four sections:[X,Y|A,B]<\/li>\n<li>Swap these sections so the outcome will be [X,A|Y,B].<\/li>\n<li>Continue recursively until A=B (right part contains one element only)<\/li>\n<li>Consider the processed parts as ONE group for the next processing.<\/li>\n<li>In case the array still contain more groups take the result group as the first group into the next loop and go to 2.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2>\u00a0For example:<\/h2>\n<ol>\n<li>Array = [<span style=\"color: #ff0000;\">1,2,3,4,5,6,7,8,<\/span><span style=\"color: #339966;\">a,b,c,d,e,f,g,h<\/span>]<\/li>\n<li>FIRST = [<span style=\"color: #ff0000;\">1,2,3,4,5,6,7,8<\/span>], SECOND = [<span style=\"color: #339966;\">a,b,c,d,e,f,g,h<\/span>]\n<ol>\n<li>X = [<span style=\"color: #ff0000;\">1,2,3,4<\/span>], Y = [<span style=\"color: #ff0000;\">5,6,7,8<\/span>], A = [<span style=\"color: #339966;\">a,b,c,d<\/span>], B = [<span style=\"color: #339966;\">e,f,g,h<\/span>]<\/li>\n<li>Array = [<span style=\"color: #ff0000;\">1,2,3,4,<\/span><span style=\"color: #339966;\">a,b,c,d,<\/span><span style=\"color: #ff0000;\">5,6,7,8,<\/span><span style=\"color: #339966;\">e,f,g,h<\/span>]<br \/>\n[X|A] = [<span style=\"color: #ff0000;\">1,2,3,4,<\/span><span style=\"color: #339966;\">a,b,c,d<\/span>]<\/li>\n<li>U = [<span style=\"color: #ff0000;\">1,2<\/span>], V = [<span style=\"color: #ff0000;\">3,4<\/span>], W = [<span style=\"color: #339966;\">a,b<\/span>], Z = [<span style=\"color: #339966;\">c,d<\/span>]<br \/>\nSwap V and W:[U,W|V,Z] = [<span style=\"color: #ff0000;\">1,2,<\/span><span style=\"color: #339966;\">a,b,<\/span><span style=\"color: #ff0000;\">3,4,<\/span><span style=\"color: #339966;\">c,d<\/span>]<br \/>\n[U|W] = [<span style=\"color: #ff0000;\">1,2,<\/span><span style=\"color: #339966;\">a,b<\/span>] swap 2 and a:<br \/>\n[<span style=\"color: #ff0000;\">1,<\/span><span style=\"color: #339966;\">a,<\/span><span style=\"color: #ff0000;\">2,<\/span><span style=\"color: #339966;\">b<\/span>]<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h1>Solution 2<\/h1>\n<ul>\n<li><span style=\"font-family: 'Helvetica Neue', Helvetica, Arial, 'Nimbus Sans L', sans-serif;\">Process all array groups from back to front<\/span><\/li>\n<li>From the currently being processed group, save the last item to temp variable, rotate the array from position 0, to the item being processed and set the temp variable as first item of the array<\/li>\n<li>Continue until all items are processed<\/li>\n<li>This approach is called in-place &#8220;matrix transposition&#8221;<\/li>\n<\/ul>\n<h2>Example<\/h2>\n<ul>\n<li><span style=\"line-height: 15px;\">ARRAY = [<span style=\"color: #ff0000;\">A,B,C<\/span>,<span style=\"color: #99cc00;\">1,2,3,<\/span><span style=\"color: #3366ff;\">X,Y,Z]<\/span><\/span><\/li>\n<li>ARRAY = [<span style=\"color: #3366ff;\">Z<\/span>,<span style=\"color: #ff0000;\">A,B,C,<\/span><span style=\"color: #99cc00;\">1,2,3,<\/span><span style=\"color: #3366ff;\">X,Y<\/span>]<\/li>\n<li>ARRAY = [<span style=\"color: #99cc00;\">3,<\/span><span style=\"color: #3366ff;\">Z,<\/span><span style=\"color: #ff0000;\">A,B,C,<\/span><span style=\"color: #99cc00;\">1,2,<\/span><span style=\"color: #3366ff;\">X,Y<\/span>]<\/li>\n<li>ARRAY = [<span style=\"color: #ff0000;\">C,<\/span><span style=\"color: #99cc00;\">3,<\/span><span style=\"color: #3366ff;\">Z,<\/span><span style=\"color: #ff0000;\">A,B,<\/span><span style=\"color: #99cc00;\">1,2,<\/span><span style=\"color: #3366ff;\">X,Y<\/span>]<\/li>\n<li>ARRAY = [<span style=\"color: #3366ff;\">Y,<\/span><span style=\"color: #ff0000;\">C,<\/span><span style=\"color: #99cc00;\">3,<\/span><span style=\"color: #3366ff;\">Z,<\/span><span style=\"color: #ff0000;\">A,B,<\/span><span style=\"color: #99cc00;\">1,2,<\/span><span style=\"color: #3366ff;\">X<\/span>]<\/li>\n<li>ARRAY = [<span style=\"color: #99cc00;\">2,<\/span><span style=\"color: #3366ff;\">Y,<\/span><span style=\"color: #ff0000;\">C,<\/span><span style=\"color: #99cc00;\">3,<\/span><span style=\"color: #3366ff;\">Z,<\/span><span style=\"color: #ff0000;\">A,B,<\/span><span style=\"color: #99cc00;\">1,<\/span><span style=\"color: #3366ff;\">X<\/span>]<\/li>\n<li>ARRAY = [<span style=\"color: #ff0000;\">B,<\/span><span style=\"color: #99cc00;\">2,<\/span><span style=\"color: #3366ff;\">Y,<\/span><span style=\"color: #ff0000;\">C,<\/span><span style=\"color: #99cc00;\">3,<\/span><span style=\"color: #3366ff;\">Z,<\/span><span style=\"color: #ff0000;\">A,<\/span><span style=\"color: #99cc00;\">1,<\/span><span style=\"color: #3366ff;\">X<\/span>]<\/li>\n<li>ARRAY = [<span style=\"color: #3366ff;\">X,<\/span><span style=\"color: #ff0000;\">B,<\/span><span style=\"color: #99cc00;\">2,<\/span><span style=\"color: #3366ff;\">Y,<\/span><span style=\"color: #ff0000;\">C,<\/span><span style=\"color: #99cc00;\">3,<\/span><span style=\"color: #3366ff;\">Z,<\/span><span style=\"color: #ff0000;\">A,<\/span><span style=\"color: #99cc00;\">1<\/span>]<\/li>\n<li>ARRAY = [<span style=\"color: #99cc00;\">1,<\/span><span style=\"color: #3366ff;\">X,<\/span><span style=\"color: #ff0000;\">B,<\/span><span style=\"color: #99cc00;\">2,<\/span><span style=\"color: #3366ff;\">Y,<\/span><span style=\"color: #ff0000;\">C,<\/span><span style=\"color: #99cc00;\">3,<\/span><span style=\"color: #3366ff;\">Z,<\/span><span style=\"color: #ff0000;\">A<\/span>]<\/li>\n<li>ARRAY = [<span style=\"color: #ff0000;\">A,<span style=\"color: #99cc00;\">1,<\/span><\/span><span style=\"color: #3366ff;\">X,<\/span><span style=\"color: #ff0000;\">B,<\/span><span style=\"color: #99cc00;\">2,<\/span><span style=\"color: #3366ff;\">Y,<\/span><span style=\"color: #ff0000;\">C,<\/span><span style=\"color: #99cc00;\">3,<\/span><span style=\"color: #3366ff;\">Z<\/span>]<\/li>\n<\/ul>\n<p>I tried to implement this solution in C++ so who is interested, here comes the source code:<\/p>\n<pre lang=\"cpp\">#include&lt;iostream&gt;\r\n#include&lt;vector&gt;\r\n\r\nusing namespace std;\r\n\r\nstruct Part {\r\n  unsigned int start;\r\n  unsigned int end;\r\n};\r\n\r\nstruct Bounds {\r\n  Part first;\r\n  Part second;\r\n};\r\n\r\nvoid printArray(vector&lt;char&gt;&amp; array){\r\n  int len = array.size();\r\n  for(int i=0; i&lt;len; i++)\r\n    cout &lt;&lt; array[i] &lt;&lt; \" \";\r\n}\r\n\r\nvoid rotateArray(vector&lt;char&gt;&amp; array, int start, int end, int num_positions) {\r\n  for(int i = 0; i &lt; num_positions; i++) {\r\n    char last = array[end];\r\n    for(int j=end; j &gt; start; j--)\r\n      array[j] = array[j-1];\r\n      array[start] = last;\r\n    }\r\n}\r\n\r\nvoid swapTwoArrayParts(vector&lt;char&gt;&amp; array, Bounds bounds) {\r\n  int first_part_items = bounds.first.end - bounds.first.start + 1;\r\n  int second_part_items = bounds.second.end - bounds.second.start + 1;;\r\n  int factor = first_part_items \/ second_part_items;\r\n\r\n  \/\/ there's nothing to sort\r\n  if (second_part_items == 1)\r\n    return;\r\n\r\n  int num_rotations = second_part_items \/ 2;\r\n  int rotate_start = bounds.first.start + num_rotations * factor;\r\n  int rotate_end = bounds.second.start + num_rotations - 1;\r\n  rotateArray(array, rotate_start, rotate_end, num_rotations);\r\n\r\n  \/\/swap left part\r\n  if (num_rotations &gt; 1){\r\n    Bounds b;\r\n    b.first.start = bounds.first.start;\r\n    b.first.end = rotate_start - 1;\r\n    b.second.start = rotate_start;\r\n    b.second.end = rotate_start + num_rotations - 1;\r\n    swapTwoArrayParts(array, b);\r\n  }\r\n  \/\/swap right part\r\n  if(second_part_items &gt; 2){\r\n    Bounds b;\r\n    b.first.start = rotate_start + num_rotations;\r\n    b.first.end = b.first.start + bounds.first.end - rotate_start;\r\n    b.second.start = b.first.end + 1;\r\n    b.second.end = bounds.second.end;\r\n    swapTwoArrayParts(array, b);\r\n  }\r\n}\r\n\r\nvoid swapArray(vector&lt;char&gt;&amp; array, int num_groups) {\r\n  if(array.size() % num_groups != 0)\r\n    throw \"Incorrect input data\";\r\n\r\n  int part_items = array.size() \/ num_groups;\r\n\r\n  \/\/ there's nothing to sort\r\n  if (part_items == 1)\r\n    return;\r\n  for(int i = 2; i &lt;= num_groups; i++) {\r\n    Bounds b;\r\n    b.first.start = 0;\r\n    b.first.end = ((i-1) * part_items) - 1;\r\n    b.second.start = b.first.end + 1;\r\n    b.second.end = (i * part_items) - 1;\r\n    swapTwoArrayParts(array, b);\r\n  }\r\n}\r\n\r\n\/******************************************\/\r\n\/* AND ANOTHER MUCH MORE ELEGANT SOLUTION *\/\r\n\/******************************************\/\r\nvoid swapArray2(vector&lt;char&gt;&amp; array, int num_groups) {\r\n  int array_size = array.size();\r\n  int num_items = array_size \/ num_groups;\r\n\r\n  for(int i=0; i&lt;num_items; i++) \r\n    for(int j=0; j&lt;num_groups; j++)\r\n      rotateArray(array, 0, (array_size-1) - j*(num_items - (i+1)), 1);\r\n}\r\n\r\nvoid loadScenario(vector&lt;char&gt;&amp; array, int* num_groups, int scenario){\r\n  switch(scenario){\r\n  case 1: {\r\n    *num_groups = 3;\r\n    array.push_back('a');\r\n    array.push_back('b');\r\n    array.push_back('c');\r\n    array.push_back('d');\r\n\r\n    array.push_back('1');\r\n    array.push_back('2');\r\n    array.push_back('3');\r\n    array.push_back('4');\r\n\r\n    array.push_back('w');\r\n    array.push_back('x');\r\n    array.push_back('y');\r\n    array.push_back('z');\r\n    }\r\n    break;\r\n  case 2: {\r\n    *num_groups = 4;\r\n    array.push_back('a');\r\n    array.push_back('b');\r\n    array.push_back('c');\r\n\r\n    array.push_back('1');\r\n    array.push_back('2');\r\n    array.push_back('3');\r\n\r\n    array.push_back('w');\r\n    array.push_back('x');\r\n    array.push_back('y');\r\n\r\n    array.push_back('p');\r\n    array.push_back('q');\r\n    array.push_back('r');\r\n    }\r\n    break;\r\n  case 3: {\r\n    *num_groups = 2;\r\n    array.push_back('a');\r\n    array.push_back('b');\r\n    array.push_back('c');\r\n    array.push_back('d');\r\n    array.push_back('e');\r\n    array.push_back('f');\r\n    array.push_back('g');\r\n\r\n    array.push_back('1');\r\n    array.push_back('2');\r\n    array.push_back('3');\r\n    array.push_back('4');\r\n    array.push_back('5');\r\n    array.push_back('6');\r\n    array.push_back('7');\r\n    }\r\n    break;\r\n  case 4: {\r\n    *num_groups = 2;\r\n    array.push_back('a');\r\n    array.push_back('b');\r\n    array.push_back('c');\r\n\r\n    array.push_back('1');\r\n    array.push_back('2');\r\n    array.push_back('3');\r\n    }\r\n    break;\r\n  }\r\n}\r\n\r\nint main(int argc, char* argv[]){\r\n  int num_groups;\r\n  vector&lt;char&gt; array;\r\n\r\n  for(int i=1; i&lt;=4; i++){\r\n    array.clear();\r\n    cout &lt;&lt; \"TEST SCENARIO: \" &lt;&lt; i &lt;&lt; endl;\r\n    loadScenario(array, &amp;num_groups,i);\r\n\r\n    cout &lt;&lt; \"Original array: \" &lt;&lt; endl;\r\n    printArray(array);\r\n\r\n    cout &lt;&lt; endl &lt;&lt; \"SWAP NOW !!!\" &lt;&lt; endl;\r\n    \/* First solution *\/\r\n    swapArray(array, num_groups);\r\n    \/* Second solution *\/\r\n    \/\/swapArray2(array, num_groups);\r\n\r\n    cout &lt;&lt; \"Swapped array: \" &lt;&lt; endl;\r\n    printArray(array);\r\n    cout &lt;&lt; endl&lt;&lt; \"************************************\" &lt;&lt; endl &lt;&lt; endl;\r\n  }\r\n  return 0;\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In a given array of elements like [a1, a2, &#8230;, an, b1, b2, &#8230;, bn, &lt;X&gt;1,&lt;X&gt;2, &#8230;, &lt;X&gt;n] without taking a extra memory swap elements in the array so the outcome will be like [a1, b1, &#8230; &lt;X&gt;1, a2, b2, &hellip; <a href=\"https:\/\/oprsteny.cz\/?p=608\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"In-place algorithm to rearrange elements of an array in C++","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[15,150,9],"tags":[161,149,162,165,164,163],"class_list":["post-608","post","type-post","status-publish","format-standard","hentry","category-algorithms","category-c-development","category-development","tag-array","tag-cpp","tag-in-place","tag-matrix-transposition","tag-recursion","tag-vector"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3nYbe-9O","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=608"}],"version-history":[{"count":10,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/608\/revisions"}],"predecessor-version":[{"id":1300,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/608\/revisions\/1300"}],"wp:attachment":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=608"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=608"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}