3

In the following algorithm for merge-sort, within the 3rd definition, first while loop there is:

a[k++] = (a[j] < b[i]) ? a[j++] : b[i++].

I understand that the RHS is a conditional statement stating that if the first operand is satisfied, then we should perform the second operand, and if it is not satisfied, we should perform the third operand.

What element does a[k++], a[j++] and b[i++] correspond to?

From my understanding, it should mean in each successive while loop, the element is incremented.

ie. beginning with the initialised values (i=1, j=m+1, k=1) for the first while loop, the next while loop will consist of (i=2, j=m+2, k=2), and so on.

Here is the entire algorithm:

# split in half
m = n / 2

# recursive sorts
sort a[1..m]
sort a[m+1..n]

# merge sorted sub-arrays using temp array
b = copy of a[1..m]
i = 1, j = m+1, k = 1
while i <= m and j <= n,
    a[k++] = (a[j] < b[i]) ? a[j++] : b[i++]
    → invariant: a[1..k] in final position
while i <= m,
    a[k++] = b[i++]
    → invariant: a[1..k] in final position
Rakete1111
  • 47,013
  • 16
  • 123
  • 162
HumanTorch
  • 349
  • 2
  • 5
  • 16
  • Does this answer your question? [Increment operator inside array](https://stackoverflow.com/questions/34250975/increment-operator-inside-array) – GSerg Jan 11 '22 at 16:34

2 Answers2

15

a[k] takes the kth element of the array a.

k++ increases the value of k, but returns the previous value.

Thus, a[k++] returns a[k] with the side-effect of increasing k after returning the value of a[k]. a[k++] = 4 is equivalent to:

a[k] = 4
k = k + 1

On the other hand, ++k would increase k before returning it, so a[++k] = 4 would be

k = k + 1
a[k] = 4
mrks
  • 8,033
  • 1
  • 33
  • 62
  • 2
    "with the side effect of increasing `k`" And confusing nobody anywhere :) – lcs Jun 23 '16 at 17:37
  • 1
    "`++k` would increase `k` before returning it". Sorry, but this can lead to an incorrect conclusion. `++k` does yield a value one greater than the `k`'s previous value, and by the next sequence point `k`'s value will have increased by one--but the two increases by 1 can happen independently. – Jerry Coffin Jun 23 '16 at 17:58
0

The increment and decrement operators work the same in array subscripts as they do in other locations. The postfix version increments the variable and returns its original value, and the prefix version increments the variable and returns its new value.

int i = 0;
do {
    if (i++) { std::cout << "i > 0" << std::endl; }
} while (i < 10);
// Checks "i"'s original value.
// First check fails, because i was 0 before incrementing.
// Outputs line 9 times.

// -----

int i = 0;
do {
    if (++i) { std::cout << "i > 0" << std::endl; }
} while (i < 10);
// Checks "i"'s incremented value.
// First check succeeds, because i is incremented before being read.
// Outputs line 10 times.

Similarly, if we have this:

int arr[5] = { 1, 2, 3, 4, 5 };
int i = 0;
do {
    std::cout << arr[i++] << std::endl;
} while (i < 5);

The variable's original value will be used as the index, and the output will be:

1
2
3
4
5

However, if we have this:

int arr[5] = { 1, 2, 3, 4, 5 };
int i = 0;
do {
    std::cout << arr[++i] << std::endl;
} while (i < 5);

The variable's incremented value is used as the index, and the output will be:

2
3
4
5

Considering this, we can take your example line, a[k++] = (a[j] < b[i]) ? a[j++] : b[i++], and read it as meaning this:

Assign value to a[k], then increment k.
  Value is conditionally determined based on:
    (a[j] < b[i])
  If true, value is:
    Read a[j], then increment j.
  If false, value is:
    Read b[i], then increment i.

It can be a useful time-saver if you know how to use it properly, but it can also make things harder to parse if used improperly.