Sorting 2d array (matrix) in C - c

I have a task to sort a 2d array but it is really hard for me. I can't figure out where I'm making a mistake.
It will be good to use while loop instead of for loop
Here is the task:
Enter a square matrix of dimensions n.
Elements below main diagonal sort in ascending order.
Elements above main diagonal sort in descending order.
Elements on main diagonal sort:
first even numbers in ascending order.
then odd numbers in descending order.
Matrix before sorting:
1 5 4 7 2
4 8 5 9 0
2 7 6 5 3
3 1 7 4 9
2 5 1 7 3
Matrix after sorting :
4 9 9 7 5
1 6 5 5 4
1 2 8 3 2
2 3 4 3 0
5 7 7 7 1
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main () {
int n, i, j, a, k, l, o;
int m[50][50];
printf ("Enter n of square matrix : \n");
scanf ("%d", &n);
printf ("Enter rows and columns numbers n :\n");
i = 0;
while (i < n) {
j = 0;
while (j < n) {
scanf ("%d", &m[i][j]);
j++;
}
i++;
}
printf ("Matrix before sorting \n");
i = 0;
while (i < n) {
j = 0;
while (j < n) {
printf ("%d ", m[i][j]);
j++;
}
printf ("\n");
i++;
}
printf ("Matrix after sorting \n");
i = 0;
while (i < n) {
j = 0;
while (j < n) {
if (i < j) {
k = j + 1;
while (k < (n - 1)) {
if (m[i][k] < m[i][k + 1]) {
a = m[i][k];
m[i][k] = m[i][k + 1];
m[i][k + 1] = a;
}
k++;
}
}
else if (i > j) {
l = i + 1;
while (l < (n - 1)) {
if (m[l][j] > m[l + 1][j]) {
a = m[l][j];
m[l][j] = m[l + 1][j];
m[l + 1][j] = a;
}
l++;
}
}
else {
if (m[i][j] % 2 == 0 && m[i + 1][j + 1] % 2 == 0) {
if (m[i][j] > m[i + 1][j + 1]) {
a = m[i][j];
m[i][j] = m[i + 1][j + 1];
m[i + 1][j + 1] = a;
}
}
if (m[i][j] % 2 != 0 && m[i + 1][j + 1] % 2 != 0) {
if (m[i][j] < m[i + 1][j + 1]) {
a = m[i][j];
m[i][j] = m[i + 1][j + 1];
m[i + 1][j + 1] = a;
}
}
}
j++;
}
i++;
}
i = 0;
while (i < n) {
j = 0;
while (j < n) {
printf ("%d ", m[i][j]);
j++;
}
printf ("\n");
i++;
}
return 0;
}
CHANGES MADE ON 02/02/2018
I need to make simple code , without things like size_t,buffer and pointers etc...
I made some code but when i use odd n number of matrix it wont work properly (for example 5x5) I don't know where i m making mistake .
#include <stdio.h>
#include <stdlib.h>
int main()
{
static int a[500][500];
int i,j,l,k,m,b,n,t,d,c;
printf("Unesite n kvadratne matrice : \n");
scanf("%d" , &n);
printf("Matrica pre sortiranja \n \n");
for ( i = 0; i < n; i++)
{
for ( j = 0; j < n ; j++)
{
scanf("%d",&a[ i ][ j ]);
}
}
for ( i = 0; i < n; i++)
{
for ( j = 0; j < n; j++)
{
if ( i > j ) // ispod dijagonale
{
for ( l = i ; l < n ; l++)
{
for ( k = j ; k < l ; k++ )
{
if ( a[ i ][ j ] > a[ l ][ k ] && k < l )
{
t = a[ i ][ j ];
a[ i ][ j ] = a[ l ][ k ];
a[ l ][ k ] = t ;
}
}
}
}
if ( i < j ) // iznad dijagonale
{
for ( m = i ; m < n ; m++)
{
for ( b = j ; b < n ; b++)
{
if ( a[ i ][ j ] < a[ m ][ b ] && m < b )
{
t = a[ i ][ j ];
a[ i ][ j ] = a[ m ][ b ];
a[ m ][ b ] = t ;
}
}
}
}
if ( i == j ) // dijagonala
{
for (d = i ; d < n ; d++)
{
for ( c = d + 1 ; c < n ; c++)
{
if ( a[ d ] [ d ] % 2 != 0 && a[ c ] [ c]%2 == 0 )
{
t = a[ d ] [ d ] ;
a[ d ] [ d ] = a[ c ] [ c] ;
a[ c ] [ c] = t ;
}
}
}
for (d = i ; d < n ; d++)
{
for ( c = d + 1 ; c < n ; c++)
{
if ( a[ d ][ d ] %2 == 0 && a[ c ][ c ] %2 ==0
&& a[ d ][ d ] > a [ c ][ c ])
{
t = a[ d ] [ d ] ;
a[ d ] [ d ] = a[ c ] [ c] ;
a[ c ] [ c] = t ;
}
else if ( a[ d ][ d ] %2 != 0 && a[ c ][ c ] %2
!=0 && a[ d ][ d ] < a [ c ][ c ])
{
t = a[ d ] [ d ] ;
a[ d ] [ d ] = a[ c ] [ c] ;
a[ c ] [ c] = t ;
}
}
}
}
}
}
printf("Posle sortiranja : \n");
for ( i = 0; i < n; i++)
{
for ( j = 0; j < n;j++)
{
printf(" %d ",a[i][j]);
}
printf("\n \n");
}
return 0;
}

It's an intriguing problem. As I outlined in a comment, I think the solution has to be tackled in three separate sorting operations:
Sorting the diagonal
Sorting the upper triangle
Sorting the lower triangle
The sequence in which those operations occur is immaterial. Indeed, if you want to run the three sorts in parallel with threads, you could do that.
The trick to sorting the diagonal is to write a comparison function that ensures that all even numbers come before all odd numbers (so every even number is deemed smaller than any odd number), but when two even numbers are compared, they're sorted in ascending order whereas when two odd numbers are compared, they're sorted in descending order. The cmp_aeod() function (ascending even odd descending) function achieves this.
It would be possible to work with just one of the cmp_asc() and cmp_dsc() functions, but it is more straight-forward to have both. The (x > y) - (x < y) idiom does two comparison always, but if x is bigger than y, the first term is 1, the second 0, and the result is 1. If x is smaller than y, the first term is 0, the second is 1, and the result is -1. If x is equal to y, of course, both terms are 0 and the result is also 0.
The key to sorting the triangles is to note that sorting algorithms work on contiguous arrays, but the data in the triangles is not contiguous. The solution shown is to number the elements in the triangle from 0 to m, where m = (n * (n - 1)) / 2, given that the square matrix is an n by n one. The code then needs to be able to identify which indexes in the matrix should be accessed for the corresponding element number, and this mapping is done by the ut or lt matrix in the triangle-sorting functions. I couldn't work out a non-iterative formula to convert the sequence number in the triangle into a row/col pair, so I created the map matrix. This gives an auxilliary storage requirement of size O(N2).
The sort algorithm used is a simple quadratic sort; you can change it for a more sophisticated algorithm (quicksort or whatever) as you wish.
/*
** + Enter a square matrix of dimensions n .
** + Elements below main diagonal sort in ascending order.
** + Elements above main diagonal sort in descending order.
** + Elements on main diagonal sort :
** - first even numbers in ascending order.
** - then odd numbers in descending order.
*/
static inline int cmp_asc(int x, int y) { return (x > y) - (x < y); }
static inline int cmp_dsc(int x, int y) { return (x < y) - (x > y); }
static inline int cmp_eaod(int x, int y)
{
int px = x & 1;
int py = y & 1;
if (px != py)
return px - py;
if (px == 1)
return cmp_dsc(x, y);
return cmp_asc(x, y);
}
#include <stdio.h>
static void print_matrix(const char *tag, size_t r, size_t c, int matrix[r][c])
{
printf("%s:\n", tag);
for (size_t i = 0; i < r; i++)
{
for (size_t j = 0; j < c; j++)
printf("%3d", matrix[i][j]);
putchar('\n');
}
}
static void sort_diagonal(size_t n, int matrix[n][n])
{
for (size_t i = 0; i < n; i++)
{
for (size_t j = i + 1; j < n; j++)
{
if (cmp_eaod(matrix[i][i], matrix[j][j]) > 0)
{
int t = matrix[i][i];
matrix[i][i] = matrix[j][j];
matrix[j][j] = t;
}
}
}
}
/*
** D0 U0 U1 U2 U3
** L0 D1 U4 U5 U6
** L1 L2 D3 U7 U8
** L3 L4 L5 D4 U9
** L6 L7 L8 L9 D5
**
** D0 = (0, 0); U0 = (0, 1); U1 = (0, 2); U2 = (0, 3); U3 = (0, 4);
** L0 = (1, 0); D1 = (1, 1); U4 = (1, 2); U5 = (1, 3); U6 = (1, 4);
** L1 = (2, 0); L2 = (2, 1); D2 = (2, 2); U7 = (2, 3); U8 = (2, 4);
** L3 = (3, 0); L4 = (3, 1); L5 = (3, 2); D3 = (3, 3); U9 = (3, 4);
** L6 = (4, 0); L7 = (4, 1); L8 = (4, 2); L9 = (4, 3); D4 = (4, 4);
*/
/*
** It is probably best to create an array that does the mapping from an
** index to the row/column, with one such mapping for the lower
** triangle; one for the upper triangle.
*/
static void sort_lt(size_t n, int matrix[n][n])
{
size_t m = (n * (n - 1)) / 2;
int lt[m][2];
size_t r = 1;
size_t c = 0;
for (size_t i = 0; i < m; i++)
{
lt[i][0] = r;
lt[i][1] = c++;
if (c == r)
{
r++;
c = 0;
}
}
//print_matrix("LT map", m, 2, lt);
for (size_t i = 0; i < m; i++)
{
size_t xi = lt[i][0];
size_t yi = lt[i][1];
for (size_t j = i + 1; j < m; j++)
{
size_t xj = lt[j][0];
size_t yj = lt[j][1];
if (cmp_asc(matrix[xi][yi], matrix[xj][yj]) > 0)
{
int t = matrix[xi][yi];
matrix[xi][yi] = matrix[xj][yj];
matrix[xj][yj] = t;
}
}
}
}
static void sort_ut(size_t n, int matrix[n][n])
{
size_t m = (n * (n - 1)) / 2;
int ut[m][2];
size_t r = 0;
size_t c = 0;
for (size_t i = 0; i < m; i++)
{
ut[i][0] = r;
ut[i][1] = ++c;
if (c == n - 1)
{
r++;
c = r;
}
}
//print_matrix("UT map", m, 2, ut);
for (size_t i = 0; i < m; i++)
{
size_t xi = ut[i][0];
size_t yi = ut[i][1];
for (size_t j = i + 1; j < m; j++)
{
size_t xj = ut[j][0];
size_t yj = ut[j][1];
if (cmp_dsc(matrix[xi][yi], matrix[xj][yj]) > 0)
{
int t = matrix[xi][yi];
matrix[xi][yi] = matrix[xj][yj];
matrix[xj][yj] = t;
}
}
}
}
static void test_matrix(const char *tag, size_t n, int matrix[n][n])
{
char buffer[64];
snprintf(buffer, sizeof(buffer), "Matrix %s (%zux%zu) - before", tag, n, n);
print_matrix(buffer, n, n, matrix);
//print_matrix("Before sorting diagonal", n, n, matrix);
sort_diagonal(n, matrix);
//print_matrix("After sorting diagonal", n, n, matrix);
sort_lt(n, matrix);
//print_matrix("After sorting lower triangle", n, n, matrix);
sort_ut(n, matrix);
//print_matrix("After sorting upper triangle", n, n, matrix);
snprintf(buffer, sizeof(buffer), "Matrix %s (%zux%zu) - after", tag, n, n);
print_matrix(buffer, n, n, matrix);
}
int main(void)
{
int matrix1[5][5] =
{
{ 1, 5, 4, 7, 2 },
{ 4, 8, 5, 9, 0 },
{ 2, 7, 6, 5, 3 },
{ 3, 1, 7, 4, 9 },
{ 2, 5, 1, 7, 3 },
};
test_matrix("SAMPLE1", 5, matrix1);
// gen_matrix -i -n matrix2 -r 10 -c 10 -L 10 -H 99
int matrix2[10][10] =
{
{ 87, 32, 98, 58, 60, 71, 46, 81, 70, 14, },
{ 22, 92, 15, 98, 51, 26, 94, 67, 46, 56, },
{ 71, 89, 86, 16, 20, 89, 97, 89, 45, 92, },
{ 63, 13, 76, 19, 75, 19, 66, 89, 58, 41, },
{ 82, 68, 75, 26, 58, 20, 89, 87, 65, 66, },
{ 74, 83, 68, 92, 10, 98, 90, 21, 39, 63, },
{ 24, 65, 23, 68, 62, 44, 48, 22, 27, 59, },
{ 26, 27, 71, 71, 51, 31, 43, 69, 92, 10, },
{ 54, 19, 41, 50, 10, 89, 42, 52, 94, 54, },
{ 42, 50, 79, 48, 77, 18, 29, 40, 61, 63, },
};
test_matrix("SAMPLE 2", 10, matrix2);
return 0;
}
When run, the output is:
Matrix SAMPLE1 (5x5) - before:
1 5 4 7 2
4 8 5 9 0
2 7 6 5 3
3 1 7 4 9
2 5 1 7 3
Matrix SAMPLE1 (5x5) - after:
4 9 9 7 5
1 6 5 5 4
1 2 8 3 2
2 3 4 3 0
5 7 7 7 1
Matrix SAMPLE 2 (10x10) - before:
87 32 98 58 60 71 46 81 70 14
22 92 15 98 51 26 94 67 46 56
71 89 86 16 20 89 97 89 45 92
63 13 76 19 75 19 66 89 58 41
82 68 75 26 58 20 89 87 65 66
74 83 68 92 10 98 90 21 39 63
24 65 23 68 62 44 48 22 27 59
26 27 71 71 51 31 43 69 92 10
54 19 41 50 10 89 42 52 94 54
42 50 79 48 77 18 29 40 61 63
Matrix SAMPLE 2 (10x10) - after:
48 98 98 97 94 92 92 90 89 89
10 58 89 89 87 81 75 71 70 67
10 13 86 66 66 65 63 60 59 58
18 19 22 92 58 56 54 51 46 46
23 24 26 26 94 45 41 39 32 27
27 29 31 40 41 98 26 22 21 20
42 42 43 44 48 50 87 20 19 16
50 51 52 54 61 62 63 69 15 14
65 68 68 68 71 71 71 74 63 10
75 76 77 79 82 83 89 89 92 19
The 'SAMPLE1 - before' data corresponds to the input in the question, and the 'SAMPLE 1 - after' output corresponds to the desired output. The bigger matrix result seems to match the requirements too.
I developed the diagonal sort first because it is by far the easiest; the even ascending, odd descending order is a problem I'd solved before. I then developed one of the triangle sorts, and debugged that. Getting the second triangle sorted was then very straight-forward. Making sure that I had a good flexible matrix printing function also helped. The commented out calls were all used at some point during the development.
Timing tests
The 'sort in place' code shown becomes very slow as the matrix grows. There's an alternative method — copy the data out of the matrix into a 1D vector; sort the vector; copy the data back into the matrix. I did some timing tests. With a matrix size of 10x10, the times were comparable (15µs for the basic sort code shown above; 12µs for code using extract, quicksort, insert). When the matrix size was 20x20, the performance was firmly in favour of the extract, quicksort, insert: 172µs vs 32µs in favour of quicksort, and by 900x900, the basic sort was taking 285s vs 0.054s for quicksort. The discrepancy is growing faster than a quadratic sort can account for. The trouble is the very complex access path to get to the elements being sorted. The code for creating the lt and ut matrices remains useful. The lt and ut matrices tell you which cells to collect the data from for sorting the triangle (order doesn't much matter while extracting the data since it is about to be sorted anyway), but also (crucially) tells you where to place each element in the sorted data.
You can find my code on GitHub in my SOQ (Stack
Overflow Questions) repository in the
src/so-4829-1562
sub-directory. (Note that at the moment, the code uses VLAs for intermediate matrices; it crashes at around 1000x1000 on a Mac. I need to change it to use dynamic memory allocation in the sort code as well as in the data generation code. It may get fixed, sooner or later. Also, I'm not convinced there's enough time between refreshes of hardware to use the basic sort on 10000x10000 size matrices, though I think the quick sort code would still be usable.)
Another interesting test would be to adapt the 'basic sort' to use extract, quadratic sort, insert when sorting the triangles. I'm pretty sure it would vastly outpace the 'basic sort' code, though it would still lose out to the O(NlogN) quick sort code as the arrays got bigger. The copying time becomes negligible compared to the sorting time.
Using qsort() etc
/* SO 4829-1562 */
#include "time.sort2d-31.h"
#include "emalloc.h"
/*
** + Enter a square matrix of dimensions n .
** + Elements below main diagonal sort in ascending order.
** + Elements above main diagonal sort in descending order.
** + Elements on main diagonal sort :
** - first even numbers in ascending order.
** - then odd numbers in descending order.
*/
/* Variation 4: Use system qsort() and common code to coordinate sorting of triangles */
/* Avoids two matrices lt and ut, thereby reducing the extra data space needed. */
static inline int cmp_asc(int x, int y) { return (x > y) - (x < y); }
static inline int cmp_dsc(int x, int y) { return (x < y) - (x > y); }
static inline int cmp_eaod(int x, int y)
{
int px = x & 1;
int py = y & 1;
if (px != py)
return px - py;
if (px == 1)
return cmp_dsc(x, y);
return cmp_asc(x, y);
}
static int qs_cmp_int_asc(const void *v1, const void *v2)
{
int i1 = *(const int *)v1;
int i2 = *(const int *)v2;
return cmp_asc(i1, i2);
}
static int qs_cmp_int_dsc(const void *v1, const void *v2)
{
int i1 = *(const int *)v1;
int i2 = *(const int *)v2;
return cmp_dsc(i1, i2);
}
static int qs_cmp_int_eaod(const void *v1, const void *v2)
{
int i1 = *(const int *)v1;
int i2 = *(const int *)v2;
return cmp_eaod(i1, i2);
}
static void sort_diagonal(size_t n, int matrix[n][n])
{
int data[n];
for (size_t i = 0; i < n; i++)
data[i] = matrix[i][i];
qsort(data, n, sizeof(data[0]), qs_cmp_int_eaod);
for (size_t i = 0; i < n; i++)
matrix[i][i] = data[i];
}
/*
** D0 U0 U1 U2 U3
** L0 D1 U4 U5 U6
** L1 L2 D3 U7 U8
** L3 L4 L5 D4 U9
** L6 L7 L8 L9 D5
**
** D0 = (0, 0); U0 = (0, 1); U1 = (0, 2); U2 = (0, 3); U3 = (0, 4);
** L0 = (1, 0); D1 = (1, 1); U4 = (1, 2); U5 = (1, 3); U6 = (1, 4);
** L1 = (2, 0); L2 = (2, 1); D2 = (2, 2); U7 = (2, 3); U8 = (2, 4);
** L3 = (3, 0); L4 = (3, 1); L5 = (3, 2); D3 = (3, 3); U9 = (3, 4);
** L6 = (4, 0); L7 = (4, 1); L8 = (4, 2); L9 = (4, 3); D4 = (4, 4);
*/
typedef void (*Copier)(int *val1, int *val2);
static void copy_a_to_b(int *val1, int *val2) { *val2 = *val1; }
static void copy_b_to_a(int *val1, int *val2) { *val1 = *val2; }
static void copy_lt_data(size_t n, int matrix[n][n], int vector[], Copier copy)
{
size_t m = (n * (n - 1)) / 2;
size_t r = 1;
size_t c = 0;
for (size_t i = 0; i < m; i++)
{
(*copy)(&matrix[r][c++], &vector[i]);
if (c == r)
{
r++;
c = 0;
}
}
}
static void copy_ut_data(size_t n, int matrix[n][n], int vector[], Copier copy)
{
size_t m = (n * (n - 1)) / 2;
size_t r = 0;
size_t c = 0;
for (size_t i = 0; i < m; i++)
{
(*copy)(&matrix[r][++c], &vector[i]);
if (c == n - 1)
{
r++;
c = r;
}
}
}
typedef void (*Mapper)(size_t n, int matrix[n][n], int vector[], Copier copy);
typedef int (*Comparator)(const void *v1, const void *v2);
static void sort_triangle(size_t n, int matrix[n][n], Mapper mapper, Comparator cmp)
{
size_t m = (n * (n - 1)) / 2;
int *data = MALLOC(m * sizeof(*data));
(*mapper)(n, matrix, data, copy_a_to_b);
qsort(data, m, sizeof(data[0]), cmp);
(*mapper)(n, matrix, data, copy_b_to_a);
FREE(data);
}
void quick_sort(size_t n, int matrix[n][n])
{
sort_diagonal(n, matrix);
sort_triangle(n, matrix, copy_lt_data, qs_cmp_int_asc);
sort_triangle(n, matrix, copy_ut_data, qs_cmp_int_dsc);
}
I also put a timing test together — see GitHub for the source code. The results were:
Basic sort (10x10) - elapsed: 0.000010
Clean sort (10x10) - elapsed: 0.000008
Quick sort (10x10) - elapsed: 0.000015
Basic sort (20x20) - elapsed: 0.000153
Clean sort (20x20) - elapsed: 0.000112
Quick sort (20x20) - elapsed: 0.000026
Basic sort (30x30) - elapsed: 0.000800
Clean sort (30x30) - elapsed: 0.000645
Quick sort (30x30) - elapsed: 0.000060
Basic sort (40x40) - elapsed: 0.002661
Clean sort (40x40) - elapsed: 0.002057
Quick sort (40x40) - elapsed: 0.000106
Basic sort (50x50) - elapsed: 0.006347
Clean sort (50x50) - elapsed: 0.005038
Quick sort (50x50) - elapsed: 0.000175
Basic sort (60x60) - elapsed: 0.014120
Clean sort (60x60) - elapsed: 0.009732
Quick sort (60x60) - elapsed: 0.000258
Basic sort (70x70) - elapsed: 0.023101
Clean sort (70x70) - elapsed: 0.016593
Quick sort (70x70) - elapsed: 0.000360
Basic sort (80x80) - elapsed: 0.035169
Clean sort (80x80) - elapsed: 0.027466
Quick sort (80x80) - elapsed: 0.000445
Basic sort (90x90) - elapsed: 0.053590
Clean sort (90x90) - elapsed: 0.039012
Quick sort (90x90) - elapsed: 0.000665
Basic sort (100x100) - elapsed: 0.074192
Clean sort (100x100) - elapsed: 0.053694
Quick sort (100x100) - elapsed: 0.000797
Basic sort (200x200) - elapsed: 0.656721
Clean sort (200x200) - elapsed: 0.478688
Quick sort (200x200) - elapsed: 0.002313
Basic sort (300x300) - elapsed: 2.826153
Clean sort (300x300) - elapsed: 2.126663
Quick sort (300x300) - elapsed: 0.004871
Basic sort (400x400) - elapsed: 8.384908
Clean sort (400x400) - elapsed: 6.374244
Quick sort (400x400) - elapsed: 0.008324
Basic sort (500x500) - elapsed: 22.083337
Clean sort (500x500) - elapsed: 16.124325
Quick sort (500x500) - elapsed: 0.014953
Basic sort (600x600) - elapsed: 43.233985
Clean sort (600x600) - elapsed: 31.362548
Quick sort (600x600) - elapsed: 0.019563
Basic sort (700x700) - elapsed: 85.463261
Clean sort (700x700) - elapsed: 60.488744
Quick sort (700x700) - elapsed: 0.027003
Basic sort (800x800) - elapsed: 148.358024
Clean sort (800x800) - elapsed: 102.991679
Quick sort (800x800) - elapsed: 0.038143
Basic sort (900x900) - elapsed: 253.434539
Clean sort (900x900) - elapsed: 150.658682
Quick sort (900x900) - elapsed: 0.045815
Quick sort (10x10) - elapsed: 0.000007
Quick sort (20x20) - elapsed: 0.000025
Quick sort (30x30) - elapsed: 0.000057
Quick sort (40x40) - elapsed: 0.000104
Quick sort (50x50) - elapsed: 0.000196
Quick sort (60x60) - elapsed: 0.000245
Quick sort (70x70) - elapsed: 0.000397
Quick sort (80x80) - elapsed: 0.000435
Quick sort (90x90) - elapsed: 0.000538
Quick sort (100x100) - elapsed: 0.000676
Quick sort (200x200) - elapsed: 0.002780
Quick sort (300x300) - elapsed: 0.005868
Quick sort (400x400) - elapsed: 0.009393
Quick sort (500x500) - elapsed: 0.016258
Quick sort (600x600) - elapsed: 0.024982
Quick sort (700x700) - elapsed: 0.031137
Quick sort (800x800) - elapsed: 0.042561
Quick sort (900x900) - elapsed: 0.052450
Quick sort (1000x1000) - elapsed: 0.061720
Quick sort (2000x2000) - elapsed: 0.229984
Quick sort (3000x3000) - elapsed: 0.480724
Quick sort (4000x4000) - elapsed: 0.826916
Quick sort (5000x5000) - elapsed: 1.308370
Quick sort (6000x6000) - elapsed: 1.890218
Quick sort (7000x7000) - elapsed: 2.559171
Quick sort (8000x8000) - elapsed: 3.346258
Quick sort (9000x9000) - elapsed: 4.359553
Quick sort (10000x10000) - elapsed: 5.345243
Quick sort (20000x20000) - elapsed: 22.189061
Quick sort (30000x30000) - elapsed: 51.385711
Quick sort (40000x40000) - elapsed: 97.543689
Quick sort (50000x50000) - elapsed: 177.373366
Quick sort (60000x60000) - elapsed: 315.083561
Quick sort (70000x70000) - elapsed: 476.135379
Quick sort (80000x80000) - elapsed: 756.888114
Quick sort (90000x90000) - elapsed: 1002.540185
At the very smallest sizes (10x10 or less), it is possible that the qsort() code is slower than the others — the difference is tiny (a few microseconds) but fairly consistent. By the time you've reached 20x20, the qsort() code is persistently faster, and the discrepancy grows. Note that the size, N, used for O(NlogN) or O(N2), corresponds to the square of the size of the matrix — so the amount of data to be sorted in a 20x20 matrix is four times the amount of data to be sorted in a 10x10 matrix. The performance of the basic sort or 'clean sort' is so bad that a 90k x 90k matrix doesn't bear thinking about, but the qsort() code sorts it in a time comparable to the time taken by the others to sort a 900 x 900 matrix (1/10,000th the size).
Fixing the code added 2018-02-02
The code added to the question on 2018-02-02 is a good attempt at solving the problem in a different way.
As noted by the OP, it sometimes fails to sort the data correctly.
The problem is that the code in the lower triangle
Here's the code fixed so it produces the correct output on the two sample matrices used previously.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
static int a[500][500];
int i, j, l, k, m, b, n, t, d, c;
printf("Unesite n kvadratne matrice:\n");
scanf("%d", &n);
printf("Matrica pre sortiranja\n\n");
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &a[i][j]);
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%3d", a[i][j]);
printf("\n");
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (i > j) // ispod dijagonale (LT)
{
int s = j + 1; // JL
for (l = i; l < n; l++)
{
//for (k = j; k < l; k++) // OP
for (k = s; k < l; k++) // JL
{
//printf("a[%d][%d] = %d <=> a[%d][%d] %d\n", // JL
// i, j, a[i][j], l, k, a[l][k]); // JL
//if (a[i][j] > a[l][k] && k < l) // OP
if (a[i][j] > a[l][k]) // JL
{
t = a[i][j];
a[i][j] = a[l][k];
a[l][k] = t;
}
}
s = 0; // JL
}
}
if (i < j) // iznad dijagonale (UT)
{
int s = j + 1; // JL
for (m = i; m < n; m++)
{
//for (b = j; b < n; b++) // OP
for (b = s; b < n; b++) // JL
{
//printf("a[%d][%d] = %d <=> a[%d][%d] %d\n", // JL
// i, j, a[i][j], m, b, a[m][b]); // JL
//if (a[i][j] < a[m][b] && m < b) // OP
if (a[i][j] < a[m][b]) // JL
{
t = a[i][j];
a[i][j] = a[m][b];
a[m][b] = t;
}
}
s = m + 2; // JL
}
}
if (i == j) // dijagonala
{
for (d = i; d < n; d++)
{
for (c = d + 1; c < n; c++)
{
if (a[d][d] % 2 != 0 && a[c][c] % 2 == 0)
{
t = a[d][d];
a[d][d] = a[c][c];
a[c][c] = t;
}
}
}
for (d = i; d < n; d++)
{
for (c = d + 1; c < n; c++)
{
if (a[d][d] % 2 == 0 && a[c][c] % 2 == 0
&& a[d][d] > a[c][c])
{
t = a[d][d];
a[d][d] = a[c][c];
a[c][c] = t;
}
else if (a[d][d] % 2 != 0 && a[c][c] % 2
!= 0 && a[d][d] < a[c][c])
{
t = a[d][d];
a[d][d] = a[c][c];
a[c][c] = t;
}
}
}
}
}
}
printf("Posle sortiranja:\n");
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%3d", a[i][j]);
printf("\n");
}
return 0;
}
The commented out printing operations were crucial to seeing what the trouble was.
Sample output
This program was sort2d-mk2-73.
$ sort2d-mk2-73 < example-2.in
Unesite n kvadratne matrice:
Matrica pre sortiranja
87 32 98 58 60 71 46 81 70 14
22 92 15 98 51 26 94 67 46 56
71 89 86 16 20 89 97 89 45 92
63 13 76 19 75 19 66 89 58 41
82 68 75 26 58 20 89 87 65 66
74 83 68 92 10 98 90 21 39 63
24 65 23 68 62 44 48 22 27 59
26 27 71 71 51 31 43 69 92 10
54 19 41 50 10 89 42 52 94 54
42 50 79 48 77 18 29 40 61 63
Posle sortiranja:
48 98 98 97 94 92 92 90 89 89
10 58 89 89 87 81 75 71 70 67
10 13 86 66 66 65 63 60 59 58
18 19 22 92 58 56 54 51 46 46
23 24 26 26 94 45 41 39 32 27
27 29 31 40 41 98 26 22 21 20
42 42 43 44 48 50 87 20 19 16
50 51 52 54 61 62 63 69 15 14
65 68 68 68 71 71 71 74 63 10
75 76 77 79 82 83 89 89 92 19
$ sort2d-mk2-73 < example-1.in
Unesite n kvadratne matrice:
Matrica pre sortiranja
1 5 4 7 2
4 8 5 9 0
2 7 6 5 3
3 1 7 4 9
2 5 1 7 3
Posle sortiranja:
4 9 9 7 5
1 6 5 5 4
1 2 8 3 2
2 3 4 3 0
5 7 7 7 1
$
For comparison, the code posted in the question (sort2d-mk2-67) generated:
$ sort2d-mk2-67 < example-2.in
Unesite n kvadratne matrice :
Matrica pre sortiranja
Posle sortiranja :
48 98 98 97 94 92 92 90 89 66
10 58 89 89 89 87 81 75 70 63
10 13 86 71 67 66 65 60 59 56
18 19 22 92 58 58 54 51 46 46
23 24 26 29 94 45 41 39 32 27
26 27 31 40 41 98 26 22 21 20
42 42 43 44 48 50 87 20 19 16
50 51 52 54 61 62 63 69 15 14
65 68 68 68 71 71 71 76 63 10
74 75 77 79 82 83 89 89 92 19
$ sort2d-mk2-67 < example-1.in
Unesite n kvadratne matrice :
Matrica pre sortiranja
Posle sortiranja :
4 9 9 7 5
1 6 5 5 3
1 2 8 4 2
2 3 5 3 0
4 7 7 7 1
$
One of the changes between sort2d-mk2-67.c and sort2d-mk2-73.c was compressing the printing; another change was to print the matrix before and after the sorting operation.
In the smaller matrix, you can see that the 3 in row 1 column 4 (counting from 0) should be the 4 in row 2 column 3.
Similarly, the 5 in row 3 column 2 should be the 4 in row 4 column 1.
The fixed code is OK.
I've not benchmarked this code (yet).

Related

Calculate maximum path cost for a matrix in C

I am learning c and encountered maximum cost path question in which
Rules:
matrix is n x n size
Starting from the cell (bottommost leftmost cell), you want to go to the topmost
rightmost cell in a sequence of steps. In each step, you can go either right or up from
your current location.
I tried to solve using dynamic programming and this is the function I have written
computecost(int *utr,int n)//utr is the input matrix
{
int *str;
int i,j;
str=(int *)malloc(n*n*sizeof(int));
for(j=0;j<n;j++)//intialization of bottom row
{
str[n*(n-1)+j]=utr[n*(n-1)+j];
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<n;j++)
{
str[n*i+j]=utr[n*i+j]+max(str[n*(i+1)+j],str[n*(i+1)+(j+1)]);
}
}
printf("%d",str[n*0+0]);
return 0;
}
and this is the input
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&str[n*i+j]);
}
}
but
for the matrix 5 x5
1 4 8 2 9
32 67 18 42 1
4 86 12 7 1
8 4 12 17 44
1 43 11 45 2
the desired output is 272 but I am getting 211.
the output matrix for my case
1 43 11 45 2
51 47 57 62 46
55 143 74 69 47
175 210 92 111 52
211 214 119 113 64
Can anyone help me?
You don't need dynamic programming for this since there are no overlapping sub-problems. Just use a simple recursion.
const int n = 5;
int mat[n][n] = {
{1,4,8,2,9},
{32,67,18,42,1},
{4,86,12,7,1},
{8,4,12,17,44},
{1,43,11,45,2}
}; // input matrix
int f(int x, int y, int sum){
if(x == 0 && y == 4)
return sum;
int p = 0, q = 0;
if(x - 1 >= 0)
p = f(x-1, y, sum + mat[x-1][y]);
if(y + 1 <= 4)
q = f(x, y+1, sum+mat[x][y+1]);
return max(p,q);
}
int main(){
int maxSum = f(4,0, mat[4][0]);
printf("%d\n", maxSum);
}
You were not very far to succeed.
In practice, you did not initialize correctly the bottom row.
Moreover, there was a little mistake in the iteration calculation.
This is the corrected code.
As said in a comment, it could be further simplified, by avoiding the use of a new array, simply updating the input array.
#include <stdio.h>
#include <stdlib.h>
int max (int a, int b) {
return (a > b) ? a : b;
}
int computecost(int *utr,int n) { //utr is the input matrix
int *str;
str = malloc (n*n*sizeof(int));
str[n*n - 1] = utr[n*n - 1];
for (int j = n-2; j >= 0; j--) { //intialization of bottom row {
str[n*(n-1)+j] = utr[n*(n-1)+j] + str[n*(n-1)+j+1]; // corrected
}
for (int i=n-2; i>=0; i--) {
str[n*i+n-1] = utr[n*i+n-1] + str[n*(i+1)+n-1];
for(int j = n-2; j >= 0; j--) {
str[n*i+j] = utr[n*i+j] + max(str[n*(i+1)+j],str[n*i + j+1]); // corrected
}
}
int cost = str[0];
free (str);
return cost;
}
int main() {
int A[25] = {
1,43,11,45,2,
8,4,12,17,44,
4,86,12,7,1,
32,67,18,42,1,
1,4,8,2,9
};
int ans = computecost (A, 5);
printf ("%d\n", ans);
return 0;
}

Eratosthenes prime numbers

I have created a program to search for prime numbers. It works without problems until the entered number is smaller than 52, when it is bigger output prints out some blank (0) numbers and I don't know why. Also other numbers have blank output.
My code is:
#include <stdio.h> //Prime numbers
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
int c[100], n, a[50], d, e, b = 1;
void sort() {
for (int i = 1; i < n; i++) {
if (c[i] > 1) {
a[b] = c[i];
printf("%d %d %d\n", a[1], b, i);
b++;
e = 2;
d = 0;
while (d <= n) {
d = c[i] * e;
c[d - 1] = 0;
e++;
}
}
}
}
int main() {
printf("Enter number as an limit:\n");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
c[i] = i + 1;
}
sort();
printf("Prime numbers between 1 and %d are:\n", n);
for (int i = 1; i < b; i++) {
printf("%d ", a[i]);
}
return 0;
}
Here is output for 25:
Enter number as an limit:
25
2 1 1
2 2 2
2 3 4
2 4 6
2 5 10
2 6 12
2 7 16
2 8 18
2 9 22
Prime numbers between 1 and 25 are:
2 3 5 7 11 13 17 19 23
But for 83 is:
Enter number as an limit:
83
2 1 1
2 2 2
2 3 4
2 4 6
2 5 10
2 6 12
2 7 16
2 8 18
2 9 22
2 10 28
2 11 30
2 12 36
2 13 40
2 14 42
2 15 46
2 16 52
0 17 58
0 18 60
0 19 66
0 20 70
0 21 72
0 22 78
0 23 82
Prime numbers between 1 and 83 are:
0 3 5 7 11 0 17 19 23 29 31 37 0 43 47 53 0 61 67 71 73 79 83
Blank spots always spots after 17th prime number. And always the blank numbers are the same. Can you help me please what is the problem?
The loop setting entries in c for multiples of c[i] runs too far: you should compute the next d before comparing against n:
for (d = c[i] * 2; d <= n; d += c[i]) {
c[d - 1] = 0;
}
As a matter of fact you could start at d = c[i] * c[i] because all lower multiples have already been seen during the previous iterations of the outer loop.
Also note that it is confusing to store i + 1 into c[i]: the code would be simpler with an array of booleans holding 1 for prime numbers and 0 for composite.
Here is a modified version:
#include <stdio.h>
int main() {
unsigned char c[101];
int a[50];
int n, b = 0;
printf("Enter number as a limit:\n");
if (scanf("%d", &n) != 1 || n < 0 || n > 100) {
printf("invalid input\n");
return 1;
}
for (int i = 0; i < n; i++) {
c[i] = 1;
}
for (int i = 2; i < n; i++) {
if (c[i] != 0) {
a[b] = i;
//printf("%d %d %d\n", a[0], b, i);
b++;
for (int d = i * i; d <= n; d += i) {
c[d] = 0;
}
}
}
printf("Prime numbers between 1 and %d are:\n", n);
for (int i = 0; i < b; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
Output:
chqrlie$ ./sieve4780
Enter number as a limit:
25
Prime numbers between 1 and 25 are:
2 3 5 7 11 13 17 19 23
chqrlie$ ./sieve4780
Enter number as a limit:
83
Prime numbers between 1 and 83 are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79
Your problem seems to be caused by the fact that you have declared an array with size 50, but in fact it goes further than that: imagine you want to use Eratosthenes' procedure to find the first 10,000 prime numbers. Does this mean that you need to declare an array of size 10,000 first (or even bigger), risking to blow up your memory?
No: best thing to do is to work with collections where you don't need to set the maximum size at declaration time, like a linked list, a vector, ..., like that you can make your list grow as much as you like during runtime.

C language wrong output...pascal triangle using 2d arrays

So this is my code for printing pascal triangle using 2d arrays but its not giving me the desired output and I cannot determine what's wrong with the logic/code.
#include <stdio.h>
int main()
{
int num, rows, col, k;
printf("Enter the number of rows of pascal triangle you want:");
scanf("%d", &num);
long a[100][100];
for (rows = 0; rows < num; rows++)
{
for (col = 0; col < (num - rows - 1); col++)
printf(" ");
for (k = 0; k <= rows; k++)
{
if (k == 0 || k == rows)
{
a[rows][k] = 1;
printf("%ld", a[rows][k]);
}
else
a[rows][k] = (a[rows - 1][k - 1]) + (a[rows - 1][k]);
printf("%ld", a[rows][k]);
}
printf("\n");
}
return 0;
}
You don't have curly braces around the statements after the else, so it looks like you'll double-printf() when the condition of the if-statement is true.
I copied the source into codechef.com/ide and changed the io for num to be just assigned to 6 which produced the following output:
Enter the number of rows of pascal triangle you want:
11
1111
11211
113311
1146411
1151010511
It looks like your close, but you want 1, 11, 121, 1331 etc right?
Wraping the else case produced the following output:
if (k == 0 || k == rows)
{
a[rows][k] = 1;
printf("(%ld)", a[rows][k]);
}
else{// START OF BLOCK HERE
a[rows][k] = (a[rows - 1][k - 1]) + (a[rows - 1][k]);
printf("(%ld)", a[rows][k]);
}//END OF BLOCK HERE, NOTE THAT IT INCLUDES THE PRINT IN THE ELSE CASE NOW
OUTPUT:
Enter the number of rows of pascal triangle you want:
(1)
(1)(1)
(1)(2)(1)
(1)(3)(3)(1)
(1)(4)(6)(4)(1)
(1)(5)(10)(10)(5)(1)
But i added () to make it clearer to me. I also added a "/n" to the end of the first printf that asks for the value of num, so that the first line is on a new line.
printf("Enter the number of rows of pascal triangle you want:\n");
You can do that without using any arrays:
#include <stdlib.h>
#include <stdio.h>
int num_digits(int number)
{
int digits = 0;
while (number) {
number /= 10;
++digits;
}
return digits;
}
unsigned max_pascal_value(int row)
{
int result = 1;
for (int num = row, denom = 1; num > denom; --num, ++denom)
result = (int)(result * (double)num / denom );
return result;
}
int main()
{
printf("Enter the number of rows of pascals triangle you want: ");
int rows;
if (scanf("%d", &rows) != 1) {
fputs("Input error. Expected an integer :(\n\n", stderr);
return EXIT_FAILURE;
}
int max_digits = num_digits(max_pascal_value(rows));
for (int i = 0; i <= rows; ++i) {
for (int k = 0; k < (rows - i) * max_digits / 2; ++k)
putchar(' ');
int previous = 1;
printf("%*i ", max_digits, previous);
for (int num = i, denom = 1; num; --num, ++denom) {
previous = (int)(previous * (double)num / denom );
printf("%*i ", max_digits, previous);
}
putchar('\n');
}
}
Output:
Enter the number of rows of pascals triangle you want: 15
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
1 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 1

Euler project problem 58, where's the error

I'm just not able to see where's the error on my code, I am getting 26249 (or 26247 if I go back one spiral level), but it should be 26241.
Obviously, there must be a problem with my logic, but I can't point out where.
Spiral Primes, Project Euler Problem 58
Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed.
37 36 35 34 33 32 31
38 17 16 15 14 13 30
39 18 05 04 03 12 29
40 19 06 01 02 11 28
41 20 07 08 09 10 27
42 21 22 23 24 25 2643 44 45 46 47 48 49
It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.
If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%?
#include <stdio.h>
#define print(ref) printf(#ref" = %d\n",ref);
#define printl(ref) printf(#ref" = %ld\n",ref);
#define NUM_OF_PRIMES 5000
int primesOnThisLevel(int);
void generatePrimes();
int isPrime(int);
int canBeExpressedAsPrime(int);
int primes[NUM_OF_PRIMES] = {2,3,5};
int primesFound = 3;
int main(){
int numbersInDiagonal = 1;
int primesInDiagonal = 0;
int level;
generatePrimes();
for (level = 2 ; numbersInDiagonal/10 <= primesInDiagonal ; level++){
primesInDiagonal += primesOnThisLevel(level);
numbersInDiagonal += 4;
}
print(numbersInDiagonal)
print(primesInDiagonal)
int sideLenght = (2*level)-1;
print(sideLenght*sideLenght);
print(sideLenght);
return 0;
}
int primesOnThisLevel(int level){
int primesCount = 0;
int sideLenght = (2*level)-1;
int differenceBetweenCorners = 2*(level-1);
int cornerValue = sideLenght*sideLenght;
for (int i = 0 ; i < 3 ; i++){
cornerValue -= differenceBetweenCorners;
primesCount += isPrime(cornerValue);
}
return primesCount;
}
void generatePrimes(){
for (int i = 7 ; primesFound < NUM_OF_PRIMES ; i +=2 ){
if ( isPrime(i) ){
primes[primesFound++] = i;
}
}
print(primes[primesFound-1]);
}
int isPrime(int prospect){
if ( prospect == 3 || prospect == 5 ) return 1;
if ( !canBeExpressedAsPrime(prospect) ) return 0;
for (int i = 0 ; primes[i]*primes[i] <= prospect ; i++)
if ( prospect%primes[i] == 0 ) return 0;
return 1;
}
int canBeExpressedAsPrime(int prospect){
if ( prospect%6 == 1 ) return 1;
if ( prospect%6 == 5 ) return 1;
return 0;
}
Special Thanks to Roberto Trani whom pointed out the error which was regarding boundaries, the previous limit included 10% which was not supposed to happen, here it is the ammended main function, which is the perfect situation to use a do-while loop.
int main(){
int numbersInDiagonal = 1;
int primesInDiagonal = 0;
int level = 2;
generatePrimes();
do {
primesInDiagonal += primesOnThisLevel(level);
numbersInDiagonal += 4;
level++;
} while ( numbersInDiagonal < primesInDiagonal*10 );
int sideLenght = (2*(--level))-1;
print(sideLenght);
return 0;
}

Analyzing quick sort in C

What I am trying to do is get the desired output below. I have tried printing in the beginning of quicksort and I am getting some of the correct values but I feel my whole approach is not working so I need some help.
level partitionNumber d [3a_spaces x1 x3 ... xn 3b_spaces]
Where:
level is the level of recursion.
partitionNumber is the number used to create the partition.
d is '>' if partitionNumber is greater than the elements of the
partition otherwise is '<'.
3a_space is a set of 3 space characters for each element of the
array before the start of the partition.
x1 x3 ... xn is the set of number in the partition. Note: print
these numbers using the "%3d" format descriptor.
3b_spaces is a set of 3 space characters for each element of the
array after the end of the partition.
desired output:
1 0 [23 13 82 33 51 17 45 75 11 27 ]
2 51> [27 13 33 23 17 45 11 ]
3 23> [11 13 17 ]
3 23> [11 13 17 ]
3 23< [ 33 45 27 ]
4 45> [ 27 33 ]
4 45> [ 27 33 ]
3 23< [ 27 33 45 ]
2 51> [11 13 17 23 27 33 45 ]
2 51< [ 82 75 ]
2 51< [ 75 82 ]
1 0 [11 13 17 23 27 33 45 51 75 82 ]
my output:
1 0 [23 13 82 33 51 17 45 75 11 27 ]
2 51> [27 13 33 23 17 45 11 ]
3 23> [11 13 17 ]
2 13> [11 13 17 ]
3 23< [ 33 45 27 ]
4 45> [ 27 33 ]
3 27? [ 27 33 ]
2 45> [ 27 33 45 ]
1 23> [11 13 17 23 27 33 45 ]
2 51< [ 82 75 ]
1 82> [ 75 82 ]
0 51> [11 13 17 23 27 33 45 51 75 82 ]
#include<stdio.h>
int inputLine[10];
void quicksort(int v[], int left, int right, int level, int previousPivotPoint, char d);
int main()
{
int v[] = { 23, 13, 82, 33, 51, 17, 45, 75, 11, 27 };
quicksort(v, 0, 9, 0, -1, ' ');
return 0;
}
void swap(int v[], int i, int j)
{
int temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
void quicksort(int v[], int left, int right, int level, int previousPivotPoint, char d)
{
int i, last;
level++;
if (previousPivotPoint > v[left]) d = '>';
else if (previousPivotPoint < v[left]) d = '<';
if (left >= right)
{
level--;
return;
}
if (previousPivotPoint == -1)
{
printf("%d 0 [", level);
} else
{
printf("%d %d%c [", level, previousPivotPoint, d);
}
previousPivotPoint = v[(left + right) / 2];
d = '?';
for (i = 0; i < 10; i++)
{
if (i > right || i < left)
{
printf(" ");
} else
{
printf("%d ", v[i]);
}
}
printf("]\n");
swap(v, left, (left + right) / 2);
last = left;
for (i = left + 1; i <= right; i++)
{
if (v[i] < v[left])
{
last++;
swap(v, last, i);
}
}
swap(v, left, last);
quicksort(v, left, last - 1, level, previousPivotPoint, d);
quicksort(v, last + 1, right, level, previousPivotPoint, d);
level--;
if (previousPivotPoint > v[left]) d = '>';
else if (previousPivotPoint < v[left]) d = '<';
printf("%d %d%c [", level, previousPivotPoint, d);
previousPivotPoint = v[(left + right) / 2];
for (i = 0; i < 10; i++)
{
if (i > right || i < left)
{
printf(" ");
} else
{
printf("%d ", v[i]);
}
}
printf("]\n");
}
A couple things I notice:
If level is going to be a modular variable instead of one passed in to the quick sort routine, it's unlikely to ever go down. Consider incorporating it into the signature of your quick sort function.
You start at i = left - this won't print your whole original underlying array. Consider always going over the array and printing them all, checking if you're in the current array or not.
You make a FORWARD declaration void swap(int v[], int i, int j); inside your quicksort routine. What's up with that? Note: apparently it's from K&R. As a matter of personal taste, I'm not the biggest fan of the notation, but you could do worse than following K&R, eh?
Didn't have time to delve into your code too deeply but here are a few
things.
First thing you should do is replace that hardcoded 10 with a
#define constant.
It should not come as a surprise that you didn't set the value of d,
hence all the spaces. Also, why make d global?
Your print loop should traverse the entire list so the part in
brackets will always be the same size.

Resources