In C: negative numbers insertion sort - c

I'm fairly new into programming and my teacher want me to implement insertion sort in C.
My code works, but not with negative numbers if I use it with negative numbers in my array I always get a segmentation fault:
void insertion_sort(int array[], int len) {
int i = 0;
int j = 1;
signed int tmp = array[0];
for(i = 1; i < len; i++) {
tmp = array[i];
j = i - 1;
if(j >= 0){
while(tmp < array[j]) {
array[j + 1] = array[j];
j = j - 1;
}
}
array[j + 1] = tmp;
}
}

Change this code snippet
if(j >= 0){
while(tmp < array[j]) {
array[j + 1] = array[j];
j = j - 1;
}
}
to
while ( j >= 0 && tmp < array[j] ) {
array[j + 1] = array[j];
j = j - 1;
}
Take into account that there is no sense to initialize defined variables
int i = 0;
int j = 1;
signed int tmp = array[0];
because they are overwritten in the followed statements.

Related

Why aren't my for loops working in this bubble sort function in C

I was having this problem to which I have come to the solution through the trial and error process but I have no idea why my bubble sort function wasn't working in the first place.
The problem had to do with the for-loops inside my function. Specifically when declaring and defining my i and j variables.
In my version of C I can define variables inside my for-loop parameter, but I can't declare them, so I do both the declaration and definition outside.
Doing so though made my function not work as intended as it didn't sort my array at all.
Though after declaring the variables outside but defining them inside the for-loop parameter to my surprise the function worked properly. My problem is I have no idea why.
Here I am providing both the working version and the non-working version:
Non-Working Version:
void bubbleDesc (int n, int array[])
{
int i = 0, j = 0, temp;
for (i; i < n - 1; i++)
{
for (j; j < n - 1; j++)
{
if (array[j] < array[j + 1])
{
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
}
Working Version:
void bubbleDesc (int n, int array[])
{
int i, j, temp;
for (i = 0; i < n - 1; i++)
{
for (j = 0; j < n - 1; j++)
{
if (array[j] < array[j + 1])
{
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
}
Your not working implementation misses the initialization of j. So it iterates the inner loop only in the first iteration of the outer loop.
void bubbleDesc (int n, int array[])
{
int i = 0, j = 0, temp;
for (i; i < n - 1; i++)
{
j = 0; // this init is needed
for (j; j < n - 1; j++)
{
if (array[j] < array[j + 1])
{
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
}
Thought, better would be to limit the scope of j and declare it only in the block where it is used, i.e., for (int j=0;...){...}
For starters it is better to specify in the function declaration the array as its first parameter and the number of elements in the array as its second parameter.
Also in C sizes of entities are defined as values of the type size_t.
So the function should be declared like
void bubbleDesc( int array[], size_t n );
In your first function implementation the variable j used in the inner for loop is initialized only once before the for loops
void bubbleDesc (int n, int array[])
{
int i = 0, j = 0, temp;
for (i; i < n - 1; i++)
{
for (j; j < n - 1; j++)
//...
though you need to initialize it to 0 each time before the inner for loop will get the control. The second function implementation does such an initialization within the for loop statement.
void bubbleDesc (int n, int array[])
{
int i, j, temp;
for ( i = 0; i < n - 1; i++ )
{
for ( j = 0; j < n - 1; j++ )
//...
Bear in mind that you should declare variables in minimum scopes where they are used. That is it will be better at least to write
void bubbleDesc (int n, int array[])
{
for ( int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1; j++)
{
if (array[j] < array[j + 1])
{
int temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
}
Or if your compiler does not allow to declare variables in the for loop statement then you can write
void bubbleDesc (int n, int array[])
{
int i = 0;
for ( ; i < n - 1; i++)
{
int j = 0;
for ( ; j < n - 1; j++)
{
if (array[j] < array[j + 1])
{
int temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
But in any case your implementation of the function is not efficient because even when the whole array or its second part is already sorted nevertheless the loops continue its iterations for all elements of the array.
Another drawback is that if you will want to sort the array in the ascending order you will have to write a new function.
You should always try to write more general functions.
It will be better to add to the function a third parameter that will specify a comparison function that will compare elements of array.
Here is a demonstration program that shows how the function can be written.
#include <stdlib.h>
void bubbleSort( int a[], size_t n, int cmp( const void *, const void * ) )
{
for (size_t last = 1; !( n < 2 ); n = last)
{
for (size_t j = last = 1; j < n; j++)
{
if (cmp( a + j, a + j - 1 ) < 0)
{
int tmp = a[j];
a[j] = a[j - 1];
a[j - 1] = tmp;
last = j;
}
}
}
}
static int ascending( const void *a, const void *b )
{
int x = *( const int * )a;
int y = *( const int * )b;
return ( y < x ) - ( x < y );
}
static int descending( const void *a, const void *b )
{
int x = *( const int * )a;
int y = *( const int * )b;
return ( x < y ) - ( y < x );
}
int main( void )
{
int a[] = { 9, 2, 6, 5, 8, 1, 3, 7, 4, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
bubbleSort( a, N, ascending );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
bubbleSort( a, N, descending );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
9 2 6 5 8 1 3 7 4 0
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0

Something is wrong with my bubble sort output

This is just a normal bubble sort code, but something is wrong in it.
#include <stdio.h>
#include <stdlib.h>
void bubble_sort(int size, int *arr);
int main(void)
{
int *array, size;
printf("enter the amount of data: ");
scanf("%d", &size);
array = (int*)malloc(sizeof(int) * size);
for (int i = 0; i < size; ++i)
{
scanf("%d", &array[i]);
}
bubble_sort(size, array);
for (int i = 0; i <= size; ++i)
{
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
void bubble_sort(int size, int *arr)
{
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
if (arr[j] > arr[j + 1])
{
int temp;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
else if (arr[j] == arr[j + 1])
{
continue;
}
}
}
}
When I execute it, a zero appear in the output when it must be print 1 2 3
[my_username#my_computer bubble_sort]$ ./bubble_sort
enter the amount of data: 3
3 1 2
0 1 2 3
^
|
Where are this zero came from?
Well, it is not quite Bubble Sort.
To start, as pointed out in the comments: arr[j + 1] accesses the array with an invalid index - one past the end of the array when j is at its maximum value (size - 1).
The loop to print the array
for(int i = 0; i <= size; ++i)
has a similar off-by-one error. i < size is the desired condition.
Accessing an array out-of-bounds invokes Undefined Behaviour.
The else if block within the sort is superfluous.
The simplified variant of bubble sort is usually written as:
void bubble_sort(int *array, size_t length)
{
for (size_t i = 0; i < length; i++) {
for (size_t j = i + 1; j < length; j++) {
if (array[i] > array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
Whereas the standard bubble sort stops if it makes a pass on the array without swapping.
void bubble_sort(int *array, size_t length)
{
int swapped;
do {
swapped = 0;
for (size_t i = 1; i < length; i++) {
if (array[i - 1] > array[i]) {
int temp = array[i - 1];
array[i - 1] = array[i];
array[i] = temp;
swapped = 1;
}
}
} while (swapped);
}
This can be optimized by observing that all elements after the last swap have already been sorted.
void bubble_sort(int *array, size_t length)
{
do {
size_t n = 0;
for (size_t i = 1; i < length; i++) {
if (array[i - 1] > array[i]) {
int temp = array[i - 1];
array[i - 1] = array[i];
array[i] = temp;
n = i;
}
}
length = n;
} while (length);
}

Stack around Variable a is corrupted

#include<stdio.h>
int main(void)
{
int array[10] = { 10,2,9,4,5,6,7,8,3,1 };
/*Implementing Bubble Sort */
int temp;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 10 - i; j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
for (int i = 0; i < 10; i++)
{
printf("%d ", array[i]);
}
}
When I try to run the program I'm getting values sorted but one value has some garbage value and the dialogue box appears that stack around variable is corrupted in VS 2019. In some other compiler I'm getting 0 in place of 10 in compiler.
The inner for .loop
for (int j = 0; j < 10 - i; j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
invokes undefined behavior because when j is equal to 9 for the first iteration of the outer loop that is when i is equal to 0 the index in the expression array[j + 1] can be equal to 10 that results in accessing the memory beyond the array.
Rewrite the loop like
for (int j = 1; j < 10 - i; j++)
{
if (array[j-1] > array[j])
{
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}
}
You can you this logic slightly edited from yours.
#include<stdio.h>
int main(void)
{
int array[10] = { 10,2,9,4,5,6,7,8,3,1 };
/*Implementing Bubble Sort */
int temp;
for (int i = 0; i < 10; i++)
{
for (int j = i; j < 10; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
for (int i = 0; i < 10; i++)
{
printf("%d ", array[i]);
}
}

Insertion sort not printing all values in C

Insertion sort is not working, it is only printing some of the values. Does anyone know what I can do to fix it?
void insertion(int Array[], int n) {
for (int i = 1; i < n; i++) {
int j = i;
while (j >= 0 && Array[j] < Array[j - 1]) {
int temp = Array[j];
Array[j] = Array[j - 1];
Array[j - 1] = temp;
j--;
}
}
}
The test in the inner loop is incorrect: when j == 0 you read and possibly modify the element at offset -1, which has undefined behavior, possibly causing the incorrect output, but since you did not post the output code, there might be other problems there.
Here is a modified version:
void insertion(int Array[], int n) {
for (int i = 1; i < n; i++) {
for (int j = i; j > 0 && Array[j] < Array[j - 1]; j--) {
int temp = Array[j];
Array[j] = Array[j - 1];
Array[j - 1] = temp;
}
}
}
Insertion Sort: Idea
 Similar to how most people arrange a hand of poker cards
Start with one card in your hand
Pick the next card and insert it into its proper sorted order
Repeat previous step for all cards

Replacing repeated values in an array in C

I'm coding a function in C to check if an array has any duplicate value, and if so replace it by any of the non-present ones. The array consists of numbers shuffled from 1 to Nmax:
unsigned char * NotRepeated (unsigned char *arr){
unsigned char i, j, count, k, notrepeated[Nmax];
k = 0;
for (i = 0; i < Nmax ; i++){
count = 0;
for (j = 0; j < Nmax; j++){
if (arr[j] != i + 1){
count++;
}
if (count == Nmax){
notrepeated[k] = i + 1;
k++;
}
}
}
k = 0;
for (i = 0; i < Nmax - 1; i++){
for (j = i + 1; j < Nmax; j++){
if (arr[i] == arr[j]){
arr[j] = notrepeated[k];
k++;
}
}
}
return arr
}
If I print the array notrepeated[k] I get almost all the array filled when the original array arr[j] seldomly has more than 2 repeated figures.
What am I doing wrong?
Thanks!

Resources