Strange Bubble sort behaviour - c

Can anyone explain why this bubble sort function doesn't work and why I lose numbers in my output? I'm very new to C, so please forgive me if this is something very obvious I have missed.
#include <stdio.h>
#include <stdlib.h>
int bubble(int array[],int length) {
int i, j;
int temp;
for(i = 0; i < (length); ++i) {
for(j = 0; j < (length - 1); ++j) {
if(array[i] > array[i+1]) {
temp = array[i+1];
array[i+1] = array[i];
array[i] = temp;
}
}
}
return 0;
}
int main() {
int array[] = {12,234,3452,5643,0};
int i;
int length;
length = (sizeof(array)/sizeof(int));
printf("Size of array = %d\n", length);
bubble(array, length);
for (i = 0; i < (length); ++i) {
printf("%d\n", array[i]);
}
return 0;
}
Output
Size of array = 5
12
234
3452
0
0

In your inner loop, you don't use j at all. Double check your logic.
Also note that array[i+1] goes beyond the array boundary.

for (i = 0; i < (length-1); ++i) {
for (j = 0; j < (length-i-1); ++j) {
if(array[j] > array[j+1]) {
temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
}
In a bubble sort you only use the inner loop variable.

Another thing, the inner loop goes from 0 to i if I remember well; but I think that's just an optimisation (as the tail is remains sorted in each step).
Try to run step by step your code with paper and pencil. That always works.

for (i = 0; i < (length); i++) {
for (j = 1; j < (length-i); j++) {
if(array[j-1] > array[j]) {
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}
}
}

Related

Bubble sort, print array per pass

How can you print the array per iteration in Bubble sort?
So far this is my sort function and im not really sure about it:
void sortBubble(int *arr)
{
int i, j;
int temp;
for (i = 0; i < SIZE; i++)
{
for (j = i + 1; j < SIZE; j++)
{
if (arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
printArr(arr); //call print function to print sorted array
}
If you want something to happen on each iteration of a loop, it should be placed within the loop body.
void sortBubble(int *arr)
{
int i, j;
int temp;
for (i = 0; i < SIZE; i++)
{
for (j = i + 1; j < SIZE; j++)
{
if (arr[i] > arr[j])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
printArr(arr);
}
}
It's also advisable to minimize the scope of variables. i, j, and temp do not need to be scoped at the function level.
void sortBubble(int *arr)
{
for (int i = 0; i < SIZE; i++)
{
for (int j = i + 1; j < SIZE; j++)
{
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
printArr(arr);
}
}
One final note: you can optimize your bubble sort by keeping track of the number of swaps performed in the inner loop. If zero swaps are performed you know the array is already sorted and you can immediately return.
Bubble sort is O(n^2) in the worst case. Your implementation is always O(n^2). This small change can reduce it to O(n) in the best case scenario, or in the realistic scenario, somewhere in between.
void sortBubble(int *arr)
{
for (int i = 0; i < SIZE; i++)
{
int swaps = 0;
for (int j = i + 1; j < SIZE; j++)
{
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
swaps++;
}
}
printArr(arr);
if (swaps == 0 /* or !swaps */) return;
}
}

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]);
}
}

Sorting array in C

I'm trying to sort an array size in C, i have ran some tests on it before i publish it here (I have left the testing statement in).
I get the correct answer once but than it moves the higher value into the wrong array, even though i have used an IF statement.
If you guys run the program it will make sense to you.
#include <stdio.h>
# define size 3
int sum();
main() {
int a[size] = { 4, 2, 3 };
int temp, i, j, x;
for (j = 0; j < size; j++){
for (i = 1; i < size; i++){
for (x = 0; x < size; x++){
printf("%d", a[x]); //testing statement;
}
printf("\n");
if (a[j] > a[i]){
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
for (x = 0; x < size; x++){
printf("%d", a[x]);
}
getch();
}
Change
for (i = 1; i < size; i++){
to something like
for (i = j + 1; i < size; i++) {
and your sort will work correctly. As it is, you're comparing the elements again with if (a[j] > a[i]){ which can move them back when you reset i to 1.

Preventing duplicates from being stored when filling dynamic array with values from two different arrays

I need to know a method to keep duplicate numbers from being stored in a new array when taking numbers from two different arrays. The function is supposed to store each 'unique' value once and not store duplicate values again.
Here is my function code so far:
int * arrayIntersect(int *sizeOfResult, const int *a, const int *b, int sizeOfA, int sizeOfB){
int i;
int j;
int k = 0;
int c[(sizeOfA + sizeOfB)];
for(j = 0; j < sizeOfB; j++){
for(i = 0; i < sizeOfA; i++){
if(a[i] == b[j]){
c[k] = a[i];
(*sizeOfResult)++;
k++;
}
}
}
int *d = (int *)malloc(sizeof(int) * *sizeOfResult);
for(i = 0; i < *sizeOfResult; i++){
d[i] = c[i];
}
return d;
}
It prints the values I need, but I want to eliminate the same number from showing up multiple times when printing the contents of the new dynamic array.
Any idea on how to improve my code to allow prevent duplication?
The proper way to do it is having the arrays ordered and then doing a binary search for each insertion like #Murilo Vasoncelos pointed out.
Below is a quick and dirty solution that loops through a and b and for each iteration checks if the number has been inserted before. If it isn't, it inserts it.
int duplicate = 0;
*sizeOfResult = 0;
for(j = 0; j < sizeOfA; j++){
for(i = 0; i < (*sizeOfResult); i++){
if(c[i] == a[j]){
duplicate = 1;
break;
}
}
if (!duplicate)
{
c[(*sizeOfResult)] = a[i];
(*sizeOfResult)++;
}
duplicate = 0;
}
for(j = 0; j < sizeOfB; j++){
for(i = 0; i < (*sizeOfResult); i++){
if(c[i] == b[j]){
duplicate = 1;
break;
}
}
if (!duplicate)
{
c[(*sizeOfResult)] = b[i];
(*sizeOfResult)++;
}
duplicate = 0;
}
If your arrays a and b are ordered, you can simply use this linear algorithm for array intersection:
int* inter(int* szr, int* a, int* b, int sza, int szb)
{
int c[MAX(sza, szb)];
int i, j, k = 0;
for (i = 0, j = 0; i < sza && j < szb;) {
if (a[i] == b[j]) {
if (k == 0 || c[k - 1] < a[i]) {
c[k++] = a[i];
}
i++;
j++;
}
else if (a[i] < b[j]) {
i++;
}
else {
j++;
}
}
*szr = k;
int* ans = (int*)malloc(sizeof(int) * k);
for (i = 0; i < k; ++i) {
ans[i] = c[i];
}
return ans;
}

Resources