All pastes #30908 Raw Edit

inplace merge

public text v1 · immutable
#30908 ·published 2005-11-24 14:02 UTC
rendered paste body
#define swap(x,t,y) do { t=x; x=y; y=t; } while(0)

void inplace_merge(int numbers[], int count)
{
	int split, join, size, actualsize, t;
	int left, middle, offset, leftwidth, i;
        //sort pairs
	for (split = 0; split < count; split += 2)
	{
		if (split < count-1)
			if (numbers[split] > numbers[split+1])
				swap(numbers[split],t,numbers[split+1]);
	}
        //merge in progressive powers of two
	for (size = 4; size < count*2; size *= 2)
	{
		for (join = 0; join < count; join+=size)
		{
			actualsize = count - join;
			if (actualsize > size)
				actualsize = size;
			offset = 0;
			left = join;
			leftwidth = size/2;
			middle = join+size/2;
                        //the left is a ring buffer, the right (aka middle) is always sorted
			while (left < middle && middle < join+actualsize) {
				if (numbers[left + offset] > numbers[middle])
				{
					swap(numbers[left],t,numbers[middle]);
					middle++;
					offset=(offset - 1 + leftwidth) % leftwidth;
				} else {
                                        //de-ring left
					while (offset)
					{
						if (offset > leftwidth / 2) {
							//Rotate left
							i = leftwidth - 1;
							t = numbers[left + i];
							for (; i; i--)
								numbers[left + i] = numbers[left + i - 1];
							numbers[left] = t;
							offset = (offset + 1) % leftwidth;
						} else {
							//Rotate right
							i = 0;
							t = numbers[left];
							for (i = 0; i < leftwidth - 1; i++)
								numbers[left + i] = numbers[left + i + 1];
							numbers[left + i] = t;
							offset--;
						}
					}
					leftwidth--;
				}
				left++;
			}
                        /* de-ring left (necessary, as the whole right
                         * could have been moved to the left
                         */
			while (offset)
			{
				if (offset > leftwidth / 2) {
					//Rotate left
					i = leftwidth - 1;
					t = numbers[left + i];
					for (; i; i--)
						numbers[left + i] = numbers[left + i - 1];
					numbers[left] = t;
					offset = (offset + 1) % leftwidth;
				} else {
					//Rotate right
					i = 0;
					t = numbers[left];
					for (i = 0; i < leftwidth - 1; i++)
						numbers[left + i] = numbers[left + i + 1];
					numbers[left + i] = t;
					offset--;
				}
			}
		}
	}
}