HiveBrain v1.2.0
Get Started
← Back to all entries
patterncModerate

Shift positive integers to the left

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
shiftlefttheintegerspositive

Problem

I would like to write a function in C that turns all negative values into zeros then shifts the positive numbers to the beginning of the array, maintaining the order of the positive integers in the array.

void shift_positives(int values[], int num_values) {
    int i;
    int last_zero = 0;
    int j;
    for (j = 0; j  0) {
            for (i = last_zero; i < j; i++) {
                if (values[i] == 0) {
                    last_zero = i;
                    break;
                }
            }
            if (last_zero < j) {
                values[last_zero] = values[j];
                values[j] = 0;
            }
        }   
    }
}


My issue with this is that it runs at \$O(N^2)\$ because of the inner for loop. Is there a more efficient way to do this?

Solution

There is a much more efficient way to do this, involving two pointers, a 'right', and a 'left' pointer. They both start at 0.

The trick is to inspect the value at the right pointer. If it is negative, increment the right pointer. If it is positive, move it to the left pointer, and increment both pointers.

This allows you to move all the positive values to the beginning of the array, in the order they were found. All you need to do then, is to zero out all the values from the left pointer to the right....

I assume that 0 is considered to be 'not positive'....

void shift_positives(int values[], int num_values) {
    int left = 0;
    for (int right = 0; right  0) {
            values[left++] = values[right];
        }
    }
    while (left < num_values) {
        values[left++] = 0;
    }
}


This performs the operation in \$O(n)\$ time. See it running on ideone

Code Snippets

void shift_positives(int values[], int num_values) {
    int left = 0;
    for (int right = 0; right < num_values; right++) {
        if (values[right] > 0) {
            values[left++] = values[right];
        }
    }
    while (left < num_values) {
        values[left++] = 0;
    }
}

Context

StackExchange Code Review Q#104090, answer score: 16

Revisions (0)

No revisions yet.