Sequential Merge Sort in C - c

I am trying to re-write a recursive Merge Sort like
void MergeSort(int* data, int size){
int half=size/2;
if (size > 1) {
MergeSort(data, half);
MergeSort(data+half, half);
Merge(data, size);
}
}
in which
void Merge(int* data, int size){
int cnt;
int cntLow=0;
int half=size/2;
int cntHigh=half;
int* sorted;
sorted = (int*) malloc(size*sizeof(int));
for (cnt=0; cnt<size; cnt++){
if (cntLow == half)
sorted[cnt] = data[cntHigh++];
else if (cntHigh == size)
sorted[cnt] = data[cntLow++];
else if (data[cntLow] <= data[cntHigh])
sorted[cnt] = data[cntLow++];
else
sorted[cnt] = data[cntHigh++];
}
for (cnt=0; cnt<size; cnt++)
data[cnt] = sorted[cnt];
free(sorted);
}
to a non-recursive call. So I wrote the function
void MergeSort_NonRecursive(int* data, int size){
int i;
int j;
for (i=size; i>0; i=i/2){
for (j=0; j<i; j++){
Merge(data + j*size/i, size/i);
}
}
}
which apparently works for sequences of size $2^n$. However, when I run it in sequences of size different than $2^n$, it does not sort right, so in some point of MergeSort_NonRecursive, my code I must be mistaken.
So where did I do wrong (in MergeSort_NonRecursive)? (also, I need to use the Merge funcion).
Thanks in advance.

Since size is an int, size/2 truncates your quotient.
e.g. if size=4, size/2 = 2. if size=5, size/2 = 2. if size=6, size/2 = 3.
So for a size of 5, you want the first MergeSort recursive call to operator on size/2 elements (i.e. the first 3), and the second call to operate on the remaining 2 elements.
You can say e.g.
int half = size/2; //size = 5: half = 2
int rest = size - half; //rest = 3
so:
void MergeSort(int* data, int size){
int half=size/2;
int rest = size-half;
if (size > 1) {
MergeSort(data, half);
MergeSort(data+half, rest); //changed this line
Merge(data, size);
}
}
Edit:
Looks like you changed the question slightly, after I posted. The general idea still stands: When you divide an int by another int, the quotient is truncated.
In your MergeSort_NonRecursive, you're dividing ints in a number of places, e.g. i=i/2, j*size/i, size/i. Pay attention to the values that you would get.

Related

How to replace a recursive function to using stack or iteration?

I have a recursive function that I wrote in C that looks like this:
void findSolutions(int** B, int n, int i) {
if (i > n) {
printBoard(B, n);
} else {
for (int x = 1; x <= n; x++) {
if (B[i][x] == 0) {
placeQueen(B, n, i, x);
findSolutions(B, n, i + 1);
removeQueen(B, n, i, x);
}
}
}
}
The initial call is (size is an integer given by user and B is a 2D array):
findSolutions(B, size, 1);
I tried to convert it into a iteration function but there is another function called removeQueen after findSolutions. I got stuck on where to put this function call. How to solve this problem? Stack is also fine but I'm also having trouble doing that.
I'm going to assume that placeQueen(B, n, i, x) makes a change to B and that removeQueen(B, n, i, x) undoes that change.
This answer shows how to approach the problem generically. It doesn't modify the algorithm like Aconcagua has.
Let's start by defining a state structure.
typedef struct {
int **B;
int n;
int i;
} State;
The original code is equivalent to the following:
void _findSolutions(State *state) {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = 1; x <= state->n; ++x) {
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
findSolutions(state2);
}
}
}
State_free(state); // Frees the board too.
}
void findSolutions(int** B, int n, int i) {
State *state = State_new(B, n, i); // Deep clones B.
_findSolutions(state);
}
Now, we're in position to eliminate the recursion.
void _findSolutions(State *state) {
StateStack *S = StateStack_new();
do {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = state->n; x>=1; --x) { // Reversed the loop to maintain order.
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
StateStack_push(S, state2);
}
}
}
State_free(state); // Frees the board too.
} while (StateStack_pop(&state));
StateStack_free(S);
}
void findSolutions(int** B, int n, int i) {
State *state = State_new(B, n, i); // Deep clones B.
_findSolutions(state);
}
We can eliminate the helper we no longer need.
void findSolutions(int** B, int n, int i) {
StateStack *S = StateStack_new();
State *state = State_new(B, n, i); // Deep clones B.
do {
if (state->i >= state->n) {
printBoard(state->B, state->n);
} else {
for (int x = state->n; x>=1; --x) { // Reversed the loop to maintain order.
if (state->B[state->i][x] == 0) {
State *state2 = State_clone(state); // Deep clone.
placeQueen(state2);
++state2->i;
StateStack_push(S, state2);
}
}
}
State_free(state); // Frees the board too.
} while (StateStack_pop(S, &state));
StateStack_free(S);
}
Functions you need to implement:
StateStack *StateStack_new(void)
void StateStack_free(StateStack *S)
void StateStack_push(StateStack *S, State *state)
int StateStack_pop(StateStack *S, State **p)
State *State_new(int **B, int n, int i) (Note: Clones B)
State *State_clone(const State *state) (Note: Clones state->B)
void State_free(State *state) (Note: Frees state->B)
Structures you need to implement:
StateStack
Tip:
It would be best if you replaced
int **B = malloc((n+1)*sizeof(int*));
for (int i=1; i<=n; ++i)
B[i] = calloc(n+1, sizeof(int));
...
for (int x = 1; x <= n; ++x)
...
B[i][x]
with
char *B = calloc(n*n, 1);
...
for (int x = 0; x < n; ++x)
...
B[(i-1)*n+(x-1)]
What you get by the recursive call is that you get stored the location of the queen in current row before you advance to next row. You will have to re-produce this in the non-recursive version of your function.
You might use another array storing these positions:
unsigned int* positions = calloc(n + 1, sizeof(unsigned int));
// need to initialise all positions to 1 yet:
for(unsigned int i = 1; i <= n; ++i)
{
positions[i] = 1;
}
I reserved a dummy element so that we can use the same indices...
You can now count up last position from 1 to n, and when reaching n there, you increment next position, restarting with current from 1 – just the same way as you increment numbers in decimal, hexadecimal or octal system: 1999 + 1 = 2000 (zero based in this case...).
for(;;)
{
for(unsigned int i = 1; i <= n; ++i)
{
placeQueen(B, n, i, positions[i]);
}
printBoard(B, n);
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, positions[i]);
}
for(unsigned int i = 1; i <= n; ++i)
{
if(++positions[i] <= n)
// break incrementing if we are in between the numbers:
// 1424 will get 1431 (with last position updated already before)
goto CONTINUE;
positions[i] = 1;
}
// we completed the entire positions list, i. e. we reset very
// last position to 1 again (comparable to an overflow: 4444 got 1111)
// so we are done -> exit main loop:
break;
CONTINUE: (void)0;
}
It's untested code, so you might find a bug in, but it should clearly illustrate the idea. It's the naive aproach, always placing the queens and removing them again.
You can do it a bit cleverer, though: place all queens at positions 1 initially and only move the queens if you really need:
for(unsigned int i = 1; i <= n; ++i)
{
positions[i] = 1;
placeQueen(B, n, i, 1);
}
for(;;)
{
printBoard(B, n);
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, positions[i]);
++positions[i]
if(++positions[i] <= n)
{
placeQueen(B, n, i, positions[i]);
goto CONTINUE;
}
placeQueen(B, n, i, 1);
positions[i] = 1;
}
break;
CONTINUE: (void)0;
}
// cleaning up the board again:
for(unsigned int i = 1; i <= n; ++i)
{
removeQueen(B, n, i, 1);
}
Again, untested...
You might discover that now the queens move within first row first, different to your recursive approach before. If that disturbs you, you can count down from n to 1 while incrementing the positions and you get original order back...
At the very end (after exiting the loop), don't forget to free the array again to avoid memory leak:
free(positions);
If n doesn't get too large (eight for a typical chess board?), you might use a VLA to prevent that problem.
Edit:
Above solutions will print any possible combinations to place eight queens on a chess board. For an 8x8 board, you get 88 possible combinations, which are more than 16 millions of combinations. You pretty sure will want to filter out some of these combinations, as you did in your original solution as well (if(B[i][x] == 0)), e. g.:
unsigned char* checks = malloc(n + 1);
for(;;)
{
memset(checks, 0, (n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[positions[i]] != 0)
goto SKIP;
checks[positions[i]] = 1;
}
// place queens and print board
SKIP:
// increment positions
}
(Trivial approach! Including the filter in the more elaborate approach will get more tricky!)
This will even be a bit more strict than your test, which would have allowed
_ Q _
Q _ _
_ Q _
on a 3x3 board, as you only compare against previous column, whereas my filter wouldn't (leaving a bit more than 40 000 boards to be printed for an 8x8 board).
Edit 2: The diagonals
To filter out those boards where the queens attack each other on the diagonals you'll need additional checks. For these, you'll have to find out what the common criterion is for the fields on the same diagonal. At first, we have to distinguish two types of diagonals, those starting at B[1][1], B[1][2], ... as well as B[2][1], B[3][1], ... – all these run from top left to bottom right direction. On the main diagonal, you'll discover that the difference between row and column index does not differ, on next neighbouring diagonals the indices differ by 1 and -1 respectively, and so on. So we'll have differences in the range [-(n-1); n-1].
If we make the checks array twice as large and shift all differences by n, can re-use do exactly the same checks as we did already for the columns:
unsigned char* checks = (unsigned char*)malloc(2*n + 1);
and after we checked the columns:
memset(checks, 0, (2 * n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[n + i - positions[i]] != 0)
goto SKIP;
checks[n + i - positions[i]] = 1;
}
Side note: Even if the array is larger, you still can just memset(checks, 0, n + 1); for the columns as we don't use the additional entries...
Now next we are interested in are the diagonals going from bottom left to top right. Similarly to the other direction, you'll discover that the difference between n - i and positions[i] remains constant for fields on the same diagonal. Again we shift by n and end up in:
memset(checks, 0, (2 * n + 1));
for(unsigned int i = 1; i <= n; ++i)
{
if(checks[2 * n - i - positions[i]] != 0)
goto SKIP;
checks[2 * n - i - positions[i]] = 1;
}
Et voilà, only boards on which queens cannot attack each other.
You might discover that some boards are symmetries (rotational or reflection) of others. Filtering these, though, is much more complicated...

How to use divide and conquer and the fact that if one subarray has a majority, the combined array has a majority to find majority element?

In the question we were told that the crux of the algorithm is the fact that
"When we get down to single elements, that single
element is returned as the majority of its (1-element) array. At every other level, it will get return values from its
two recursive calls. The key to this algorithm is the fact that if there is a majority element in the combined array,
then that element must be the majority element in either the left half of the array, or in the right half of the array."
My implementation was this, probably very buggy but the general idea was this:
#include <stdio.h>
int merge(int *input, int left, int middle, int right, int maj1, int maj2)
{
// determine length
int length1 = middle - left + 1;
int length2 = right - middle;
// create helper arrays
int left_subarray[length1];
int right_subarray[length2];
// fill helper arrays
int i;
for (i=0; i<length1; ++i)
{
left_subarray[i] = input[left + i];
}
for (i=0; i<length2; ++i)
{
right_subarray[i] = input[middle + 1 + i];
}
left_subarray[length1] = 100;
right_subarray[length2] = 100;
//both return majority element
int count1 = 0;
int count2 = 0;
for (int i = 0; i < length1; ++i) {
if (left_subarray[i] == maj1) {
count1++;
}
if (right_subarray[i] == maj1) {
count1++;
}
}
for (int i = 0; i < length2; ++i) {
if (right_subarray[i] == maj2) {
count2++;
}
if (left_subarray[i] == maj2) {
count2++;
}
}
if (count1 > ((length1+length2) - 2)/2){
return maj1;
}
else if (count2 > ((length1+length2) - 2)/2){
return maj2;
}
else
return 0;
}
int merge_sort(int *input, int start, int end, int maj1, int maj2)
{
//base case: when array split to one
if (start == end){
maj1 = start;
return maj1;
}
else
{
int middle = (start + end ) / 2;
maj1 = merge_sort(input, start, middle, maj1, maj2);
maj2 = merge_sort(input, middle+1, end, maj1, maj2);
merge(input, start, middle, end, maj1, maj2);
}
return 0;
}
int main(int argc, const char* argv[])
{
int num;
scanf("%i", &num);
int input[num];
for (int i = 0; i < num; i++){
scanf("%i", &input[i]);
}
int maj;
int maj1 = -1;
int maj2 = -1;
maj = merge_sort(&input[0], 0, num - 1, maj1, maj2);
printf("%d", maj);
return 0;
}
This obviously isn't divide and conquer. I was wondering what is the correct way to implement this, so I can have a better understanding of divide and conquer implementations. My main gripe was in how to merge the two sub-array to elevate it to the next level, but I am probably missing something fundamental on the other parts too.
Disclaimer: This WAS for an assignment, but I am analyzing it now to further my understanding.
The trick about this particular algorithm, and why it ends up O(n log n) time is that you still need to iterate over the array you are dividing in order to confirm the majority element. What the division provides is the correct candidates for this iteration.
For example:
[2,1,1,2,2,2,3,3,3,2,2]
|maj 3| maj 2
maj 2 | maj None
<-------------------> still need to iterate
This is implicit in the algorithm statement: "if there is a majority element in the combined array, then that element must be the majority element in either the left half of the array." That "if" indicates confirmation is still called for.

Nth Fibonacci using pointers in C; recursive and array

I have this code so far. It works and does what I want it to. I'm wondering if I could make it better. I do not really care for user input or any other "finish touches," just want to make the code more efficient and maybe more useful for future projects.
Excessive comments are for my personal use, I find it easier to read when I go back to old projects for references and what not.
Thanks!
#include<stdio.h>
#include<stdlib.h>
void fabonacci(int * fibArr,int numberOfSeries){
int n;
//allocate memory size
fibArr = malloc (sizeof(int) * numberOfSeries);
//first val, fib = 0
*fibArr = 0;//100
fibArr++;
//second val, fib = 1
*fibArr = 1;//104
fibArr++;
//printing first two fib values 0 and 1
printf("%i\n%i\n", *(fibArr- 2),*(fibArr- 1));
//loop for fib arr
for(n=0;n<numberOfSeries -2;n++,fibArr++){
//108 looking back at 104 looking back at 100
//112 looking back at 108 looking back at 104
*fibArr = *(fibArr-1) + *(fibArr -2);
//printing fib arr
printf("%i\n", *fibArr);
}
}
int main(){
//can implm user input if want
int n = 10;
int *fib;
//calling
fabonacci(fib,n);
}
Your code is halfway between two possible interpretations and I can't tell which one you meant. If you want fibonacci(n) to just give the nth number and not have any external side effects, you should write it as follows:
int fibonacci(int n) {
int lo, hi;
lo = 0;
hi = 1;
while(n-- > 0) {
int tmp = hi;
lo = hi;
hi = lo + tmp;
}
return lo;
}
You need no mallocs or frees because this takes constant, stack-allocated space.
If you want, instead, to store the entire sequence in memory as you compute it, you may as well require that the memory already be allocated, because this allows the caller to control where the numbers go.
// n < 0 => undefined behavior
// not enough space allocated for (n + 1) ints in res => undefined behavior
void fibonacci(int *res, int n) {
res[0] = 0;
if(n == 0) { return; }
res[1] = 1;
if(n == 1) { return; }
for(int i = 2; i <= n; i++) {
res[i] = res[i-1] + res[i-2];
}
}
It is now the caller's job to allocate memory:
int main(){
int fib[10]; // room for F_0 to F_9
fibonacci(fib, 9); // fill up to F_9
int n = ...; // some unknown number
int *fib2 = malloc(sizeof(int) * (n + 2)); // room for (n + 2) values
if(fib2 == NULL) { /* error handling */ }
fibonacci(fib2 + 1, n); // leave 1 space at the start for other purposes.
// e.g. you may want to store the length into the first element
fib2[0] = n + 1;
// this fibonacci is more flexible than before
// remember to free it
free(fib2);
}
And you can wrap this to allocate space itself while still leaving the more flexible version around:
int *fibonacci_alloc(int n) {
int *fib = malloc(sizeof(int) * (n + 1));
if(fib == NULL) { return NULL; }
fibonacci(fib, n);
return fib;
}
One way to improve the code is to let the caller create the array, and pass the array to the fibonacci function. That eliminates the need for fibonacci to allocate memory. Note that the caller can allocate/free if desired, or the caller can just declare an array.
The other improvement is to use array notation inside of the fibonacci function. You may be thinking that the pointer solution has better performance. It doesn't matter. The maximum value for n is 47 before you overflow a 32-bit int, so n is not nearly big enough for performance to be a consideration.
Finally, the fibonacci function should protect itself from bad values of n. For example, if n is 1, then the function should put a 0 in the first array entry, and not touch any other entries.
#include <stdio.h>
void fibonacci(int *array, int length)
{
if (length > 0)
array[0] = 0;
if (length > 1)
array[1] = 1;
for (int i = 2; i < length; i++)
array[i] = array[i-1] + array[i-2];
}
int main(void)
{
int fib[47];
int n = sizeof(fib) / sizeof(fib[0]);
fibonacci(fib, n);
for (int i = 0; i < n; i++)
printf("fib[%d] = %d\n", i, fib[i]);
}

Finding cyclic single transposition vector in C

I have the input as array A = [ 2,3,4,1]
The output is simply all possible permutation from elements in A which can be done by single transposition (single flip of two neighbouring elements) operation. So the output is :
[3,2,4,1],[ 2,4,3,1],[2,3,1,4],[1,3,4,2]
Circular transpositioning is allowed. Hence [2,3,4,1] ==> [1,3,4,2] is allowed and a valid output.
How to do it in C?
EDIT
In python, it would be done as follows:
def Transpose(alist):
leveloutput = []
n = len(alist)
for i in range(n):
x=alist[:]
x[i],x[(i+1)%n] = x[(i+1)%n],x[i]
leveloutput.append(x)
return leveloutput
This solution uses dynamic memory allocation, this way you can do it for an array of size size.
int *swapvalues(const int *const array, size_t size, int left, int right)
{
int *output;
int sotred;
output = malloc(size * sizeof(int));
if (output == NULL) /* check for success */
return NULL;
/* copy the original values into the new array */
memcpy(output, array, size * sizeof(int));
/* swap the requested values */
sotred = output[left];
output[left] = output[right];
output[right] = sotred;
return output;
}
int **transpose(const int *const array, size_t size)
{
int **output;
int i;
int j;
/* generate a swapped copy of the array. */
output = malloc(size * sizeof(int *));
if (output == NULL) /* check success */
return NULL;
j = 0;
for (i = 0 ; i < size - 1 ; ++i)
{
/* allocate space for `size` ints */
output[i] = swapvalues(array, size, j, 1 + j);
if (output[i] == NULL)
goto cleanup;
/* in the next iteration swap the next two values */
j += 1;
}
/* do the same to the first and last element now */
output[i] = swapvalues(array, size, 0, size - 1);
if (output[i] == NULL)
goto cleanup;
return output;
cleanup: /* some malloc call returned NULL, clean up and exit. */
if (output == NULL)
return NULL;
for (j = i ; j >= 0 ; j--)
free(output[j]);
free(output);
return NULL;
}
int main()
{
int array[4] = {2, 3, 4, 1};
int i;
int **permutations = transpose(array, sizeof(array) / sizeof(array[0]));
if (permutations != NULL)
{
for (i = 0 ; i < 4 ; ++i)
{
int j;
fprintf(stderr, "[ ");
for (j = 0 ; j < 4 ; ++j)
{
fprintf(stderr, "%d ", permutations[i][j]);
}
fprintf(stderr, "] ");
free(permutations[i]);
}
fprintf(stderr, "\n");
}
free(permutations);
return 0;
}
Although some people think goto is evil, this is a very nice use for it, don't use it to control the flow of your program (for instance to create a loop), that is confusing. But for the exit point of a function that has to do several things before returning, it think it's actually a nice use, it's my opinion, for me it makes the code easier to understand, I might be wrong.
Have a look at this code I have written with an example :
void transpose() {
int arr[] = {3, 5, 8, 1};
int l = sizeof (arr) / sizeof (arr[0]);
int i, j, k;
for (i = 0; i < l; i++) {
j = (i + 1) % l;
int copy[l];
for (k = 0; k < l; k++)
copy[k] = arr[k];
int t = copy[i];
copy[i] = copy[j];
copy[j] = t;
printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
}
}
Sample Output :
{5, 3, 8, 1}
{3, 8, 5, 1}
{3, 5, 1, 8}
{1, 5, 8, 3}
A few notes:
a single memory block is preferred to, say, an array of pointers because of better locality and less heap fragmentation;
the cyclic transposition is only one, it can be done separately, thus avoiding the overhead of the modulo operator in each iteration.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *single_transposition(const int *a, unsigned int n) {
// Output size is known, can use a single allocation
int *out = malloc(n * n * sizeof(int));
// Perform the non-cyclic transpositions
int *dst = out;
for (int i = 0; i < n - 1; ++i) {
memcpy(dst, a, n * sizeof (int));
int t = dst[i];
dst[i] = dst[i + 1];
dst[i + 1] = t;
dst += n;
}
// Perform the cyclic transposition, no need to impose the overhead
// of the modulo operation in each of the above iterations.
memcpy(dst, a, n * sizeof (int));
int t = dst[0];
dst[0] = dst[n-1];
dst[n-1] = t;
return out;
}
int main() {include
int a[] = { 2, 3, 4, 1 };
const unsigned int n = sizeof a / sizeof a[0];
int *b = single_transposition(a, n);
for (int i = 0; i < n * n; ++i)
printf("%d%c", b[i], (i % n) == n - 1 ? '\n' : ' ');
free(b);
}
There are many ways to tackle this problem, and most important questions are: how you're going to consume the output and how variable is the size of the array. You've already said the array is going to be very large, therefore I assume memory, not CPU will be the biggest bottleneck here.
If output is going to be used only few times (especially just once), it'll may be best to use functional approach: generate every transposition on the fly, and never have more than one in memory at a time. For this approach many high level languages would work as well as (maybe sometimes even better than) C.
If size of the array is fixed, or semi-fixed (eg few sizes known at compile-time), you can define structures, using C++ templates at best.
If size is dynamic and you still want to have every transposition in memory then you should allocate one huge memory block and treat it as contiguous array of arrays. This is very simple and straightforward on machine level. Unfortunately it's best tackled using pointer arithmetic, one feature of C/C++ that is renowned for being difficult to understand. (It isn't if you learn C from basics, but people jumping down from high level languages have proven track record of getting it completely wrong first time)
Other approach is to have big array of pointers to smaller arrays, which results in double pointer, the ** which is even more terrifying to newcomers.
Sorry for long post which is not a real answer, but IMHO there are too many questions left open for choosing the best solution and I feel you need bit more C basic knowledge to manage them on your own.
/edit:
As other solutions are already posted, here's a solution with minimum memory footprint. This is the most limiting approach, it uses same one buffer over and over, and you must be sure that your code is finished with first transposition before moving on to the next one. On the bright side, it'll still work just fine when other solutions would require terabyte of memory. It's also so undemanding that it might be as well implemented with a high level language. I insisted on using C++ in case you would like to have more than one matrix at a time (eg comparing them OR running several threads concurrently).
#define NO_TRANSPOSITION -1
class Transposable1dMatrix
{
private:
int * m_pMatrix;
int m_iMatrixSize;
int m_iCurrTransposition;
//transposition N means that elements N and N+1 are swapped
//transpostion -1 means no transposition
//transposition (size-1) means cyclic transpostion
//as usual in C (size-1) is the last valid index
public:
Transposable1dMatrix(int MatrixSize)
{
m_iMatrixSize = MatrixSize;
m_pMatrix = new int[m_iMatrixSize];
m_iCurrTransposition = NO_TRANSPOSITION;
}
int* GetCurrentMatrix()
{
return m_pMatrix;
}
bool IsTransposed()
{
return m_iCurrTransposition != NO_TRANSPOSITION;
}
void ReturnToOriginal()
{
if(!IsTransposed())//already in original state, nothing to do here
return;
//apply same transpostion again to go back to original
TransposeInternal(m_iCurrTransposition);
m_iCurrTransposition = NO_TRANSPOSITION;
}
void TransposeTo(int TranspositionIndex)
{
if(IsTransposed())
ReturnToOriginal();
TransposeInternal(TranspositionIndex);
m_iCurrTransposition = TranspositionIndex;
}
private:
void TransposeInternal(int TranspositionIndex)
{
int Swap1 = TranspositionIndex;
int Swap2 = TranspositionIndex+1;
if(Swap2 == m_iMatrixSize)
Swap2 = 0;//this is the cyclic one
int tmp = m_pMatrix[Swap1];
m_pMatrix[Swap1] = m_pMatrix[Swap2];
m_pMatrix[Swap2] = tmp;
}
};
void main(void)
{
int arr[] = {2, 3, 4, 1};
int size = 4;
//allocate
Transposable1dMatrix* test = new Transposable1dMatrix(size);
//fill data
memcpy(test->GetCurrentMatrix(), arr, size * sizeof (int));
//run test
for(int x = 0; x<size;x++)
{
test->TransposeTo(x);
int* copy = test->GetCurrentMatrix();
printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
}
}

why doesn't my quicksort implementation in C work

Here I made a quicksort implementation that uses (at least tries to) a little trick that is possible because I know the input is a list of numbers in the set {1,2,...,1023}. In particular I am not using a pivot that is necessarily in the list itself. Here is the main part of the function
int partition2(int length, int arr[], int mask) {
int left = 0;
int right = length;
while (left < right) {
while ((left < right) && (!((arr[left])&mask)) ) {
left++;
}
while ((left < right) && ((arr[right-1])&mask)) {
right--;
}
if (left < right) {
right--;
swap(left, right, arr);
left++;
}
}
left--;
return left;
}
void qSort2(int length, int arr[], int mask) {
int boundary;
if (length <= 1) {
return; /* empty or singleton array: nothing to sort */
}
boundary = partition2(length, arr, mask);
qSort2(boundary, arr,mask/2);
qSort2(length - boundary - 1, &arr[boundary + 1], mask/2);
}
main(){
int length = 200;
int *arr;
arr = generateNumbers(length);
qSort2(length, arr, 512);
int i;d
for(i=0;i<length;i++){
printf("%d ", arr[i]);
}
}
Sorry for the lengthy code. The function generateNumbers just makes a vector of size length with numbers from the given range and swap simply swaps two elements from the array. Now I am trying to exploit the fact that all numbers are smaller that 1024. So roughly speaking half of them will contain a 1 in binary representation in the position corresponding to 2^9=512. So we can use that to split the list in two lists. Then we check for both list what the digit corresponding to 2^8 is and split the list again. I am using the variable mask for this and the operator n&mask is zero if the is smaller then mask and non zero if it is larger that mask. For some reason though, it does not seem to work. Does anyone have any idea why? The output list is almost sorted but there are just some mistakes at certain places. If anyone could help me out that would be great. Thanks!
Here is the generateNumbers function:
void *makeDynamicIntArray(int length) {
void *ptr = malloc(length*sizeof(int));
if (ptr == NULL) {
printf("\nMalloc failed: out of memory?\n");
exit(-1);
}
return ptr;
}
int *generateNumbers(int length) {
int i, *arr = makeDynamicIntArray(length);
for (i=0; i<length; i++) {
arr[i] = rand() % 1024;
}
return arr;
}

Resources