Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>EDIT</strong></p> <p>Your edits made my original answer (below) nonsensical to other readers :) Oh, well...</p> <p>First thing is to decide if Your <code>begin</code> and <code>end</code> pointers define a range [begin, end) or [begin, end]. I suggest the first choice because it is used in C++ library. If You agree with that, the call </p> <pre><code>mergesort(arr,&amp;arr[0],&amp;arr[n]); </code></pre> <p>is correct. You have to change <code>&amp;arr[n]</code> to <code>&amp;arr[n-1]</code> only if You decide, You want the pointers <code>begin</code> and <code>end</code> to define the range [begin, end] which I suggest not to do.</p> <p>In fact the pointers <code>begin</code> and <code>end</code> are enough to sort the range and Your <code>mergesort</code> function doesn't need the first parameter.</p> <p>The calculation of <code>med</code> is incorrect</p> <pre><code>med=arr[arr_end-arr_begin]/2+arr_begin; </code></pre> <p>It was correct in the previous version (the variable was named q)</p> <p>The calls below are also incorrect</p> <pre><code>mergesort(arr,arr_begin,med); mergesort(arr,med+1,arr_end); </code></pre> <p>First call is supposed to sort the range [arr_begin, med) , not [arr_begin, med] (<code>*med</code> doesn't belong to that range), so the second call should sort the range starting at <code>med</code>.</p> <p>The allocation of arr1 is correct, thanks to the fact, that the difference <code>end - begin</code> is equal to the number of elements. That's the advantage of picking the range [begin, end) instead of [begin, end]. It would be nice however, if You freed the allocated memory after use.</p> <p>The call to merge is incorrect, like the calls to <code>mergesort</code> above. The second range sholuld start at <code>med</code> because <code>med</code> points past the first range, not at it's last element.</p> <p>The implementation of <code>merge</code> is overcomplicated. You don't have to swap anything. You just take elements from both ranges and copy them to the destination. Those three while loops that started my original post (below) are enough, but pay attention to the conditions.</p> <p>I repeat once again <code>med</code> points <strong>past</strong> the first range and <code>arr_end</code> points <strong>past</strong> the second range. Taking it into consideration, should You use <code>&lt;=</code> or <code>&lt;</code> operators?</p> <hr> <p>I don't like the inconsistency in the conditions <code>i&lt;=q</code>, <code>j&lt;=u</code>, <code>i&lt;q</code>, <code>j&lt;u</code> in the following code:</p> <pre><code>while(i&lt;=q &amp;&amp; j&lt;=u){ if(*i&lt;*j){ *k=*i; i=i+1; } else{ *k=*j; j=j+1; } k=k+1; } while(i&lt;q){*k=*i;i++;k++;} while(j&lt;u){*k=*j;j++;k++;} </code></pre> <p>You call Your mergesort like this:</p> <pre><code>mergesort(arr,&amp;arr[0],&amp;arr[n]); </code></pre> <p>which means, that <code>u</code> is a pointer, that points to the spot <strong>after the last element of Your array</strong>. In other words, You seem to think of Your pointers, like of iterators <code>begin</code> and <code>end</code> which define the range [begin, end) - <code>*begin</code> belongs to the range, but <code>*end</code> not,</p> <p>In the definition of <code>mergesort</code> You write</p> <pre><code>int *q=((u-p)/2)+p; mergesort(arr,p,q); mergesort(arr,q+1,u); </code></pre> <p>which is inconsistent with the assumptions above. <code>q</code> may be equal <code>p</code> if <code>u == p+1</code>.</p> <p><code>mergesort(arr,p,q);</code> means sort the range [p, q) (<code>q</code> is past the range) <code>mergesort(arr,q+1,u);</code> means sort the range [q+1, u) (<code>u</code> is past the range)</p> <p>If You were consistent in Your representation of a range with pointers, You would never touch the element <code>*q</code> this way.</p> <p>Thinking of the range as [begin, end) instead of [begin, end] (in the second case <code>*end</code> is part of the range) is consistent with the way iterators are used in C++, but it's not obligatory. You can use pointers to define the range also the second way, but in that case, You have to change the call <code>mergesort(arr,&amp;arr[0],&amp;arr[n]);</code> to <code>mergesort(arr,&amp;arr[0],&amp;arr[n-1]);</code>. <strong>In both cases You have to rethink conditions in the code cited at the beginning</strong>.</p> <p>This is a homework, so I won't solve it for You, but here is a little hint, that might help thinking about it. Redefine Your <code>merge</code> so it takes 2 ranges, to merge, explicitly:</p> <pre><code>void merge(int * destination, int * r1_begin, int * r1_end, int * r2_begin, int * r2_end); </code></pre> <p>and think how to use it. Later You can simplify things. You don't really need destination parameter, and You don't have to copy all merged elements. You can copy only one range first and then, merge directly into destination, taking elements from the copy of the first range and from the second range.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload