Majority element in an array.It - c

#include <stdio.h>
void main()
{
int maj, count, n = 6;
int arr[] = {1, 2, 2, 2, 2, 3, 4};
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 0;
for (int j = 9; j < n; j++) {
if (arr[j] == maj) count++;
}
if (count > n / 2) {
break; /* I think some problem is here ,if majority element not found then it takes last element as the majority element */
}
}
printf("%d", maj);
}
It is giving correct output if majority ellement is there but incorrect output if no majority element is there for example if array is {1,2,3,4} it is giving output as 4. please help!!

#include <stdio.h>
int main() {
int maj, count, n = 7; //n is size of arr
int arr[] = {1, 2, 2, 2, 2, 3, 4};
int isFound = 0; //0 -> false, 1 -> true
for (int i = 0; i < n; i++) {
maj = arr[i];
count = 1; //first elements is itself
isFound = 0; //by default we assume that no major elements is found
for (int j = i+1; j < n; j++) { //iterate from next elements onwards to right in array
if (arr[j] == maj) count++;
}
if (count > n / 2) {
isFound = 1;
break; //major elements found; no need to iterator further; just break the loop now
}
}
if(isFound) printf("%d ", maj);
else printf("no major element");
return 0;
}

For starters according to the C Standard function main without parameters shall be declared like
int main( void )
Try not to use magic numbers. Usually as in your program they are a reason for program bugs. For example you declared the array arr as having 7 elements however the variable n that should keep the number of elements in the array is initialized with the value 6. Another magic number 9 is used in the loop
for (int j = 9; j < n; j++) {
^^^
There is no need to write the outer loop that travers the whole array. Also the program does not report the case when the majority number does not exist in the array.
Using your approach with two loops the program can look the following way
#include <stdio.h>
int main( void )
{
int a[] = { 1, 2, 2, 2, 2, 3, 4 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t i = 0;
for ( ; i < ( N + 1 ) / 2; i++ )
{
size_t count = 1;
for ( size_t j = i + 1; count < N / 2 + 1 && j < N; j++ )
{
if ( a[i] == a[j] ) ++count;
}
if ( !( count < N / 2 + 1) ) break;
}
if ( i != ( N + 1 ) / 2 )
{
printf( "The majority is %d\n", a[i] );
}
else
{
puts( "There is no majority element" );
}
return 0;
}
Its output is
The majority is 2

Related

dealing with dups in end of the array

This is the task I have got:
I need to write a function (not recursive) which has two parameters.
An array of integers.
An integer representing the size of the array.
The function will move the duplicates to an end of the array.
And will give the size of the different digits.
Example:
5 , 2 , 4 , 5 , 6 , 7 , 2, n = 7
we will get back 5 , 2 , 4 , 6 , 7 , 5 , 2 and 5
We must keep the original sort as it is (which means like in example 5 must)
It does not matter how we sort the duplicates ones but just keep the sort for the original array as it is)
The function has to print the number of different digits (like in example 5)
The the input range of numbers in array [-n,n]
I can only use 1 additional array for help.
It has to be O(n)
I tried it so many times and feel like am missing something. Would appreciate any advice/suggestions.
int moveDup(int* arr, int n)
{
int* C = (int*)calloc(n * 2 + 1, sizeof(int));
assert(C);
/*int* count = C + n;*/
int *D = arr[0];
int value = 0, count = 0;
for (int i = 0; i < n; i++)
{
value = arr[i];
if (C[value + n] == 0)
{
*D = arr[i];
D++;
count++;
}
C[value + n] = C[value + n] + 1;
}
while (1 < C[value + n])
{
*D = i;
D++;
C[value + n]--;
}
free(C);
return count;
}
This algorithm will produce the required results in O(n) arithmetic complexity:
Input is an array A with n elements indexed from A0 to An−1 inclusive. For each Ai, −n ≤ Ai ≤ n.
Create an array C that can be indexed from C−n to C+n, inclusive. Initialize C to all zeros.
Define a pointer D. Initialize D to point to A0.
For 0 ≤ i < n:
If CAi=0, copy Ai to where D points and advance D one element.
Increment CAi.
Set r to the number of elements D has been advanced from A0.
For −n ≤ i ≤ +n:
While 1 < CAi:
Copy i to where D points and advance D one element.
Decrement CAi.
Release C.
Return r. A contains the required values.
A sample implementation is:
#include <stdio.h>
#include <stdlib.h>
#define NumberOf(a) (sizeof (a) / sizeof *(a))
int moveDuplicates(int Array[], int n)
{
int *memory = calloc(2*n+1, sizeof *Array);
if (!memory)
{
fprintf(stderr, "Error, unable to allocate memory.\n");
exit(EXIT_FAILURE);
}
int *count = memory + n;
int *destination = Array;
for (int i = 0; i < n; ++i)
// Count each element. If it is unique, move it to the front.
if (!count[Array[i]]++)
*destination++ = Array[i];
// Record how many unique elements were found.
int result = destination - Array;
// Append duplicates to back.
for (int i = -n; i <= n; ++i)
while (0 < --count[i])
*destination++ = i;
free(memory);
return result;
}
int main(void)
{
int Array[] = { 5, 2, 4, 5, 6, 7, 2 };
printf("There are %d different numbers.\n",
moveDuplicates(Array, NumberOf(Array)));
for (int i = 0; i < NumberOf(Array); ++i)
printf(" %d", Array[i]);
printf("\n");
}
here is the right answer, figured it out by myself.
int moveDup(int* arr, int n)
{
int* seen_before = (int*)calloc(n * 2 + 1, sizeof(int));
assert(seen_before);
int val = 0, count = 0, flag = 1;
int j = 0;
for (int i = 0; i < n; i++)
{
val = arr[i];
if (seen_before[arr[i] + n] == 0)
{
seen_before[arr[i] + n]++;
count++;
continue;
}
else if (flag)
{
j = i + 1;
flag = 0;
}
while (j < n)
{
if (seen_before[arr[j] + n] == 0)
{
count++;
seen_before[arr[j] + n]++;
swap(&arr[i], &arr[j]);
j++;
if (j == n)
{
free(seen_before);
return count;
}
break;
}
/*break;*/
j++;
if (j == n)
{
free(seen_before);
return count;
}
}
}
}
second right answer
int* mem = (int*)calloc(2 * n + 1, sizeof * arr);
assert(mem);
int* count = mem + n;
int* dest = arr;
for (i = 0; i < n; ++i)
{
if (count[arr[i]]++ == 0)
{
*dest = arr[i];
*dest++;
}
}
res = dest - arr;
for (i = -n; i <= n; ++i)
{
while (0 < --count[i])
{
*dest++ = i;
}
}
free(mem);
return res;

Find the smallest number in an array that is not in another array

Currently I am trying to solve this task: Two arrays of five integers each are given. Find the lowest number in the first array that is not in the second array.
It seems to me that if the user enters such integers in the first array:
0 1 2 3 4
And the integers of the second array:
0 2 3 4 5
The lowest integer, according to the condition of the task, will be 1, because it is not in the second array.
So here is my code:
#include <stdio.h>
#include <locale.h>
int main() {
setlocale(LC_ALL, "Rus");
int arr1[5]; //initialize arrays
int arr2[5];
printf("Enter integers\n");
for (int i = 0; i < 5; i++) {
int element;
scanf_s("%d", &element);
arr1[i] = element;
}
printf("Enter integers\n");
for (int i = 0; i < 5; i++) {
int element;
scanf_s("%d", &element);
arr2[i] = element;
}
int min1 = arr1[0];
int min2 = arr2[0];
for (int i = 0; i < 5; i++) { // algorithm for finding the minimum number of an array 1
if (min1 > arr1[i]) {
min1 = arr1[i];
}
if (min2 > arr2[i]) {
min2 = arr2[i];
}
}
}
Well, the code is very clear, but here's how to make this check, if the first array input 0 1 2 3 4 and the second 0 2 3 4 5 then how to remove this zero.
There are some issues ...
We don't care about the min value for arr2--only for arr1
We must scan all arr2 values for a match to the current/candidate value of arr1
There are some special cases we must handle
Normally, if we're just looking for the min value in arr1 (e.g. arr2 is not a factor), we can do [as you've done]:
int min1 = arr1[0];
And, we could start indexing into arr1 from 1 in the for loop.
But, this fails if:
arr1[0] is the min value in arr1 and that value is in arr2
arr1 and arr2 have identical values [even if they are in a different order].
So, we need an extra [boolean] value to denote whether the min1 value is valid. And, we must start indexing in the for loop from 0.
Here is the refactored code. It is annotated:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <locale.h>
#define A1MAX 5
#define A2MAX 5
int
main(void)
{
setlocale(LC_ALL, "Rus");
// define arrays
int arr1[A1MAX];
int arr2[A2MAX];
printf("Enter integers\n");
for (int i = 0; i < A1MAX; i++) {
if (scanf("%d", &arr1[i]) != 1) {
printf("missing arr1[%d] -- %s\n",i,strerror(errno));
return 2;
}
}
printf("Enter integers\n");
for (int i = 0; i < A2MAX; i++) {
if (scanf("%d", &arr2[i]) != 1) {
printf("missing arr2[%d] -- %s\n",i,strerror(errno));
return 3;
}
}
int nomin = 1;
int min1 = arr1[0];
// check all values in arr1
for (int i = 0; i < A1MAX; i++) {
// current value we're going to test
int val = arr1[i];
// check value if it's a _new_ minimum or we do _not_ yet have a minimum
if ((val < min1) || nomin) {
// scan all elements of arr2, looking for a match to the current
// arr1 value
int match = 0;
for (int j = 0; j < A2MAX; j++) {
match = (val == arr2[j]);
if (match)
break;
}
// if the current value is _not_ in arr2, we have a new minimum
if (! match) {
min1 = val;
nomin = 0;
}
}
}
if (nomin)
printf("there are no elements in arr1 that are not in arr2\n");
else
printf("the minimum element in arr1 not in arr2 is: %d\n",min1);
return nomin;
}
Things get complicated with code tries to maintain multiple indexes into multiple arrays... Things are simplified if you re-use code and break out functions (that can test user input, too)...
#include <stdio.h>
void fill( int arr[], size_t sz ) { // Get user input (with checking)
printf("Enter integers\n");
for( size_t i = 0; i < sz; i++ )
if( scanf( "%d", &arr[i] ) != 1 ) {
fprintf( stderr, "scanf failure\n" );
exit(1);
}
}
// Search for a value in an array. Return index if found, or size if not found
size_t hunt( int val, int arr[], size_t sz ) {
for( size_t i = 0; i < sz; i++ )
if( val == arr[i] )
return i;
return sz;
}
int main() {
#if 0 // Normal with user entry
int arr1[5], arr2[5];
size_t a1sz = sizeof arr1/sizeof arr1[0];
size_t a2sz = sizeof arr2/sizeof arr2[0];
fill( arr1, a1sz );
fill( arr2, a2sz );
#else // less tedious with compile time init of data
int arr1[] = { 0, 1, 2, 3, 4 };
int arr2[] = { 0, 2, 3, 4, 5 };
size_t a1sz = sizeof arr1/sizeof arr1[0];
size_t a2sz = sizeof arr2/sizeof arr2[0];
#endif
size_t gotOne = 0;
for( size_t i = 0; i < a1sz; i++ ) {
// don't bother testing values if got a candidate and value is larger
if( gotOne && arr1[i] >= arr1[ gotOne ] ) continue;
// following is TRUE when not found...
if( hunt( arr1[i], arr2, a2sz ) == a2sz )
gotOne = i + 1;
}
if( gotOne )
printf( "Smallest in arr1 not in arr2 = %u\n", arr1[ gotOne - 1 ] );
else
puts( "No such value matching criteria" );
return 0;
}
Smallest in arr1 not in arr2 = 1
Algorithm
The naive approach to this, and one that works very well for small datasets, is to nest a couple of loops. This approach grows in time complexity very fast. O(m*n) where m is the length of the first array and n is the length of the second array.
Fortunately, we can approach this in a way that does not involve nested loops. This assumes both arrays contain only unique values. If they have duplicates, removing those duplicates would be a necessary step before the below can be performed.
Let's start with a couple of simple arrays:
int foo[] = {1, 4, 7, 9, 2};
int bar[] = {4, 1, 6, 7, 3};
Let's combine them into another array. This is a linear operation.
{1, 4, 7, 9, 2, 4, 1, 6, 7, 3}
Let's then use qsort to sort them. This operation is typically O(n*log n).
{1, 1, 2, 3, 4, 4, 6, 7, 7, 9}
Now, we can do a linear loop over these and find the unique elements. These are the ones present in one but not both of the arrays.
{2, 3, 6, 9}
But this doesn't tell us which is in the first array. That sounds like a nested loop issue. Instead, though, let's combine that with the first array.
{1, 4, 7, 9, 2, 2, 3, 6, 9}
And we'll sort this.
{1, 2, 2, 3, 4, 6, 7, 9, 9}
Now we'll scan for the first repeated number.
2
An implementation
Note: Does not check for malloc errors.
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b) {
int c = *(const int *)a;
int d = *(const int *)b;
if (c == d) return 0;
else if (c < d) return -1;
else return 1;
}
int min_not_in_2nd_array(int *result, int *arr1, size_t m, int *arr2, size_t n) {
int *temp = malloc(sizeof(int) * (m + n));
//if (!temp) return 0;
for (size_t i = 0; i < m; ++i) temp[i] = arr1[i];
for (size_t i = 0; i < n; ++i) temp[m+i] = arr2[i];
qsort(temp, m+n, sizeof(int), cmp);
int *uniques = malloc(sizeof(int) * (m + n));
//if (!uniques) return 0;
size_t n_uniques = 0;
int cur = temp[0] - 1;
size_t cur_count = 0;
for (size_t i = 0; i < m+n; ++i) {
if (i == m+n-1 && temp[i] != temp[i-1]) {
uniques[n_uniques++] = temp[i];
}
else if (temp[i] != cur) {
if (cur_count == 1) uniques[n_uniques++] = cur;
cur = temp[i];
cur_count = 1;
}
else {
cur_count++;
}
}
//for (size_t i = 0; i < n_uniques; ++i) printf("%d ", uniques[i]);
//printf("\n");
int *temp2 = malloc(sizeof(int) * (m + n_uniques));
// if (!temp2) return 0;
for (size_t i = 0; i < m; ++i) temp2[i] = arr1[i];
for (size_t i = 0; i < n_uniques; ++i) temp2[m+i] = uniques[i];
qsort(temp2, m+n_uniques, sizeof(int), cmp);
int found = 0;
for (size_t i = 0; i < m+n_uniques-1; ++i) {
if (temp2[i] == temp2[i+1]) {
*result = temp2[i];
found = 1;
break;
}
}
free(temp);
free(uniques);
free(temp2);
return found;
}
int main(void) {
int foo[] = {1, 4, 7, 9, 2};
int bar[] = {4, 1, 6, 7, 3};
int baz;
if (min_not_in_2nd_array(&baz, foo, sizeof(foo)/sizeof(*foo),
bar, sizeof(bar)/sizeof(*bar))) {
printf("Min not in 2nd array is %d\n", baz);
}
else {
printf("All elements shared.\n");
}
return 0;
}

How to sort an array that going down and then going up, to array that going down all the way?

I have an assignment to make a function that sort array that going down and then going up (for example: 9, 8, 7, 6, 5, 7, 11, 13) to array that going down all the way (for example: 13, 11, 9, 8, 7, 7, 6, 5).
I wrote this in online compiler (programiz), but it just doesn't work for me.
#include <stdio.h>
#include <stdlib.h>
#define N 10
void sort_dec_inc(int a[], int n) {
int pivot, i, q = 0;
int c[n];
for (i=0; i<n; i++) {
c[i] = 0;
}
for (i=0; i<n-1; i++) {
if (a[i]<a[i+1]) {
pivot=i+1;
break;
}
}
if (pivot == n-1) {
return;
}
for (i=0; i<pivot && n>=pivot; q++) {
if (a[i]>=a[n]) {
c[q] = a[i];
i++;
}
else {
c[q] = a[n];
n--;
}
}
if (n==pivot) {
while(i<pivot) {
c[q] = a[i];
q++;
i++;
}
}
else {
while (n>=pivot) {
c[q] = a[n];
q++;
n--;
}
}
for(i=0; i<n; i++) {
a[i] = c[i];
}
}
int main()
{
int num_arr[N] = {9, 7, 5, 3, 1, 2, 4, 6, 8, 10};
sort_dec_inc(num_arr, N);
int i;
for(i = 0; i < N; i++) {
printf("%d ", num_arr[i]);
}
return 0;
}
output (most of the times) : 9 7 5 3 1 2 4 6 8 10
Sometimes the output is different, for example: (410878976 10 9 8 1 2 4 6 8 10 )
If someone can answer in simple code its the best, I don't understand yet all the options in C.
(I'm sorry if its a clumsy code, I'm new for this.)
thanks a lot!
Solution based on the comments below:
#include <stdio.h>
#include <stdlib.h>
#define N 10
void sort_dec_inc(int a[], int n) {
int left, i = 0;
int right = n-1;
int c[n];
while (i<n) {
if (a[left] >= a[right]) {
c[i] = a[left];
left++;
}
else {
c[i] = a[right];
right--;
}
i++;
}
for(i=0; i<n; i++) {
a[i] = c[i];
}
}
int main()
{
int num_arr[N] = {9, 7, 5, 3, 1, 2, 4, 6, 8, 10};
sort_dec_inc(num_arr, N);
int i;
for(i = 0; i < N; i++) {
printf("%d ", num_arr[i]);
}
return 0;
}
output: 10 9 8 7 5 5 4 3 2 1
For starters it is a bad idea to define an auxiliary variable length array. Such an approach is unsafe because the program can report that there is no enough memory to allocate the array.
At least this code snippet
for (i=0; i<n-1; i++) {
if (a[i]<a[i+1]) {
pivot=i+1;
break;
}
}
if (pivot == n-1) {
return;
}
contains a logical error.
Consider an array that contains only two elements { 1, 2 }. In this case a[0] is less than a[i+1] that is than a[1]. So the condition of the if statement
if (pivot == n-1) {
return;
}
evaluates to logical true and the function returns the control though the array was not sorted in the descending order. It stays unchanged.
Or consider this code snippet
if (a[i]>=a[n]) {
c[q] = a[i];
i++;
}
The expression a[n] accesses memory beyond the array that results in undefined behavior.
A straightforward approach is to use the method insertion sort.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
void insertion_sort( int a[], size_t n )
{
size_t i = 1;
while ( i < n && !( a[i-1] < a[i] ) ) i++;
for ( ; i < n; i++ )
{
size_t j = i;
while ( j != 0 && a[j-1] < a[i] ) --j;
if ( i != j )
{
int tmp = a[i];
memmove( a + j + 1, a + j, ( i - j ) * sizeof( int ) );
a[j] = tmp;
}
}
}
int main( void )
{
int a[] = { 9, 7, 5, 3, 1, 2, 4, 6, 8, 10 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
insertion_sort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
9 7 5 3 1 2 4 6 8 10
10 9 8 7 6 5 4 3 2 1
I would recommend a bubble sort.
It is an easy way to sort numbers in numerical order:
for (int i = 0; i < quant; i++)
{
for (int j = 0; j < quant-1; j++)
{
if (Array[j] < Array[j + 1])
{
int temp = Array[j];
Array[j] = Array[j + 1];
Array[j + 1] = temp;
}
}
}
quant is the quantity of numbers you want to sort. Don't forget to define an integer array with length quant for the sorting process.
To access the array, just use a for loop to return all the results.

Copying an unsorted C array into another while avoiding duplicates

Hello everyone and thanks for your time.
For exercise, I wanted to write a program which copies all elements from an array to another array but without the duplicates. The only condition is that I cannot change the original array - so no sorting.
I tried making a function which checks if the current element of array1 is found in the array we copy to (array2). If no, we then copy the element to the second array and increase the size by one.
However, it does not work:
If I have
int array1[15] = {3,2,4,7,9,1,4,6,7,0,1,2,3,4,5};
int array2[15];
array2 should contain the following numbers: 3,2,4,7,9,1,6,0,5
But my output is as follows: 3,2,4,7,9,1,6
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int already_exists(int array2[], int size_arr2, int element)
{
int i;
for(i=0; i<size_arr2; i++)
{
if(array2[i] == element)
return 1;
}
return 0;
}
int main()
{
int array1[15] = {3,2,4,7,9,1,4,6,7,0,1,2,3,4,5};
int array2[15];
int i;
int size_arr2=0;
for(i=0; i<9; i++)
{
int element = array1[i];
if(already_exists(array2, size_arr2, element) == 1)
continue;
else
{
array2[size_arr2] = element;
size_arr2++;
}
}
for(i=0; i<size_arr2; i++)
{
printf("%d, ", array2[i]);
}
return 0;
}
You have a typo in the for loop
for(i=0; i<9; i++)
The array array1 contains 15 elements. So the loop should look like
for ( i = 0; i < 15; i++ )
The reason of the error is that you are using "magic numbers" instead of named constants.
Nevertheless the program in whole is inefficient because the function already_exists is called for each element of the array array1. At least you could declare it as an inline function.
Moreover it should be declared like
int already_exists( const int array2[], size_t size_arr2, int element );
Instead of this function it is better to write a function that performs the full operation.
Here is a demonstrative program.
#include <stdio.h>
size_t copy_unique( const int a1[], size_t n1, int a2[] )
{
size_t n2 = 0;
for ( size_t i = 0; i < n1; i++ )
{
size_t j = 0;
while ( j < n2 && a2[j] != a1[i] ) j++;
if ( j == n2 ) a2[n2++] = a1[i];
}
return n2;
}
int main(void)
{
enum { N = 15 };
int array1[N] = { 3, 2, 4, 7, 9, 1, 4, 6, 7, 0, 1, 2, 3, 4, 5 };
int array2[N];
for ( size_t i = 0; i < N; i++ ) printf( "%d ", array1[i] );
putchar( '\n' );
size_t n2 = copy_unique( array1, N, array2 );
for ( size_t i = 0; i < n2; i++ ) printf( "%d ", array2[i] );
putchar( '\n' );
return 0;
}
Its output is
3 2 4 7 9 1 4 6 7 0 1 2 3 4 5
3 2 4 7 9 1 6 0 5

Sorting array only with while and if

I get a message when I try to run the program. Why?
Segmentation fault
my code:
#include <stdio.h>
void sort_array(int *arr, int s);
int main() {
int arrx[] = { 6, 3, 6, 8, 4, 2, 5, 7 };
sort_array(arrx, 8);
for (int r = 0; r < 8; r++) {
printf("index[%d] = %d\n", r, arrx[r]);
}
return(0);
}
sort_array(int *arr, int s) {
int i, x, temp_x, temp;
x = 0;
i = s-1;
while (x < s) {
temp_x = x;
while (i >= 0) {
if (arr[x] > arr[i]) {
temp = arr[x];
arr[x] = arr[i];
arr[i] = temp;
x++;
}
i++;
}
x = temp_x + 1;
i = x;
}
}
I think that the problem is in the if statement.
What do you think? Why does it happen? I think that I use in positive way with the pointer to the array.
Thank you!
This loop in your program
while (i >= 0) {
//...
i++;
}
does not make sense because i is increased unconditionly.
The program can look the following way
#include <stdio.h>
void bubble_sort( int a[], size_t n )
{
while ( !( n < 2 ) )
{
size_t i = 0, last = 1;
while ( ++i < n )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
last = i;
}
}
n = last;
}
}
int main( void )
{
int a[] = { 6, 3, 6, 8, 4, 2, 5, 7 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
bubble_sort( a, N );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
return 0;
}
The program output is
6 3 6 8 4 2 5 7
2 3 4 5 6 6 7 8
If you want that the sorting function had only one while loop then you can implement it the following way
void bubble_sort( int a[], size_t n )
{
size_t i = 0;
while ( ++i < n )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
i = 0;
}
}
}
In your inner loop, you increment i beyond the size of the array. Your algorithm should require you to decrement i instead, but I am not sure this would be enough to fix the sorting algorithm.
You should first try to implement Bubble sort with a single while loop where you compare adjacent items and step back whenever you swap them.

Resources