Possible mistake in bubble sort c program - c

I was reading the book "Computer Organization and Design" by Patterson and Hennesy (5th Edition) and found this bubble sort code:
void sort (int v[], int n)
{
int i,j;
for (i=0; i<n; i+=1) {
for (j = i-1; j>=0 && v[j] > v[j+1]; j+=1) {
swap(v,j);
}
}
}
void swap (int v[], int k) {
int temp;
temp = v[k];
v[k] = v[k+1];
v[k+1] = temp;
}
I don't understand how this function would sort an array. Especially if the first element of the array is also the largest, it seems to me that the index j would go out of bounds. Running the code and printing the indices confirmed this.
This is the code I used:
#include <stdio.h>
void swap (int v[], int k) {
int temp;
temp = v[k];
v[k] = v[k+1];
v[k+1] = temp;
}
void sort (int v[], int n)
{
int i,j;
for (i=0; i<n; i+=1) {
printf("%d \n", i);
for (j = i-1; j>=0 && v[j] > v[j+1]; j+=1) {
printf("%d, %d \n", i, j);
swap(v,j);
}
}
}
int main() {
int x[3] = {5,1,2};
int N = 3;
sort(x, N);
for(int i = 0; i < 3; i++) {
printf("%d ", x[i]);
}
return 0;
}
This was the result:
/Users/mauritsdescamps/Desktop/test/cmake-build-debug/test
0
1
1, 0
1, 1
1, 2
1, 3
1, 4
2
2, 1
2, 2
2, 3
Process finished with exit code 6
Is there something I am forgetting? If not, I think there must be a mistake in the second loop condition. I have seen other implementations of the algorithm but I want to know how to get this approach to work.

I've tried this code, too. I have compiled it with GCC and somehow it worked for me (the exit status of the program was 0 and the array was sorted correctly). But I also think that their is a problem with the second loop. I would change the j+= 1 instruction into j-=1. Otherwise the second loop could end in an infinite loop. Additionally I would change the i=0 instruction in the first loop into a i=1 instruction, because it would end in an unnecessary iteration.

Related

My selection sort is very weird (code in C)

My selection sort successfully sorts certain numbers yet fails on some. The code seems very logical to me, I even printed step-by-step but somehow it does not work.
#include <stdio.h>
#include <string.h>
int number[] = {2, 5, 3, 1};
int length;
void sort(void);
void swap(int *xp, int *yp);
int main(void)
{
length = sizeof(number)/sizeof(number[0]);
for (int i = 0; i < length; i++)
{
printf("%i ", number[i]);
}
printf("\n");
sort();
}
void sort(void)
{
//number
for (int i = 0; i < length - 1; i++)
{
int max = i;
//printf("max:%i\n",max);
for (int j = i + 1; j < length; j++)
{
//printf("max:%i and j: %i\n",number[max], number[j]);
if (number[j] > number[max])
{
max = j;
//SWAP WINNER
swap(&number[max], &number[i]);
}
}
for (int k = 0; k < length; k++)
{
printf("%i ", number[k]);
}
printf("\n");
}
printf("\nnow:\n");
for (int k = 0; k < length; k++)
{
printf("%i ", number[k]);
}
printf("\n");
}
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
With the result:
2 5 3 1
3 2 5 1
3 5 2 1
3 5 2 1
now:
3 5 2 1 ~/ $
Anyway, another question, why does it have to use pointers? Because it won't work without them. Any suggestions?
The bug is in this block:
if (number[j] > number[max])
{
max = j;
//SWAP WINNER
swap(&number[max], &number[i]);
}
after max = j, max is the index of the largest number found so far. But then, you swap that number with the number at i, so max no longer references the largest number.
Selection sort is a fairly simple algorithm and you are needlessly complicating it by using a separate variable to keep track of the max value's index.
My suggestions:
Remove the max variable.
Start the outer loop from the last index and decrement it down to the first so that index i will always point to the last index in the sub-array, that is the index at which the max number is to be placed.
Run the inner loop from the first index to i-1.
After making these changes, compare array[i] with array[j] in the inner loop and swap if array[j] is greater.

How to fix this code output is not showing in rat in mace problem

I'm solving this rat in mace problem by recursion.
A Maze is given as N*N binary matrix of blocks where source block is the upper left most block i.e., maze[0][0] and destination block is lower rightmost block i.e., maze[N-1][N-1]. A rat starts from source and has to reach the destination. The rat can move only in two directions: forward and down.
In the maze matrix, 0 means the block is a dead end and 1 means the block can be used in the path from source to destination. Note that this is a simple version of the typical Maze problem.
This code i write by my own but output is not showing
#include <stdio.h>
//#where a[][] means denoting maze and b[][] means solution matrix and i put all zero in b[][]
int move(int a[3][3], int, int);
int recursion(int a[3][3], int b[3][3], int i, int j);
int main() {
int i, j, n = 3, a[20][20], b[20][20];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
scan("%d", &a[i][j]);
print("\n");
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
scan("%d", &b[i][j]);
print("\n");
}
int move(int a[3][3], int i, int j);
int recursion(int a[3][3], int b[3][3], int i, int j);
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
print("%d", b[i][j]);
print("\n");
}
return 0;
}
int recursion(int a[3][3], int b[3][3], int i, int j) {
if (move(a, i, j) == 1) {
b[i][j] = 1;
if (recursion(a, b, i, j + 1) == 1)
return 1;
if (recursion(a, b, i + 1, j) == 1)
return 1;
b[i][j] = 0;
return -1;
}
return -1;
}
int move(int a[3][3], int i, int j) {
int n = 3;
if (i >= 0 && i < n && j >= 0 && j < n && a[i][j] == 1) {
return 1;
}
return -1;
}
This code does not show output please help me where is the error that its not showing output.
I expect the result will be if i take in maze array
for example a[][] is maze matrix
110
101
111
in solution matrix and print b[][] denoting solution matrix
this is actual solution i want
100
100
111
everything is fine but output is not showing.
Here i took 3 by 3 matrix to solve only the problem is output is not showing
Welcome to Stack Overflow, and welcome to C programming.
There is a lot that is wrong with your code. The first thing that jumps out at me are the lines:
int move(int a[3][3], int i, int j);
int recursion(int a[3][3], int b[3][3], int i, int j);
inside of your main() (lines 22 and 24). I imagine that what you intend to be doing there is calling move() and recursion(), but the syntax you are using is for a function declaration, not function calling.
Second, after both of your loops with scan() in them, i and j are each going to be "3"; I'm betting you want to call move() with i of "0" and j of "0", but that's not the value they will have after those input loops.
Third, speaking of scan(), my compiler warns about scan() and print() being implicitly defined; from context, I'm betting you want scanf() and printf().
Fourth, if you are inputing literally:
110
101
111
000
000
000
then you aren't even making it out of your input loops. Your input loops perform a total of 18 inputs, so your input would be more like:
1
1
0
1
0
1
1
1
1
0
0
0
0
0
0
0
0
0
(This is after I replaced scan() with scanf(), per my note above.)
Fifth, you declare move() and recursion() as accepting as their first parameters a type int[3][3], but a and b are of type int[20][20]; your input populates (part of) a and b, but you aren't going to be able to pass a nor b as the array arguments to move() and recursion().
I have not even looked into the logic of your functions. Likely, there are several other issues, as well.
I strongly recommend you start much smaller and much simpler. e.g., here's a much simpler program that compiles as-is without warnings, and will give you immediate feedback on what it is doing. Add to this in small steps, including relevant output lines, so that you can see exactly how it is all taking shape.
#include <stdio.h>
int main() {
int i, j, n = 3, input;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &input);
printf("input is : %d\n", input);
}
}
printf("i and j are : %d, %d\n", i, j);
return 0;
}
Good luck as you learn C -- there are great things ahead for you!

Bubble sort logic, number of iterations

I have the following code:
// C program for implementation of Bubble sort
#include <stdio.h>
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
// Last i elements are already in place
for (j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]);
}
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("n");
}
// Driver program to test above functions
int main()
{
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr)/sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
return 0;
}
The only part that makes me confused is where i < n-1 in the first for loop and J< n-i-1 in the inner for loop inside the BubbleSort function. Why arent they both set to i <= n-1 and J<=n-i-1? For instance, the first iteration would be a total of n= 7, therefore it means it should go through the loop for 6 times in the outer loop and 6 times in the inner for loop. But, without the <= sign it would only be 5 iterations per loop. On the website, it has illustrated that both loops do go through 6 iterations however Im not sure how would that happen without the <=in place.
Source: https://www.geeksforgeeks.org/bubble-sort/
Note the use of arr[j+1]. Let's say your array has n = 7. Then when i = 0 and j = n - i - 1 = 6, you would be accessing arr[j+1] = arr[6 + 1] = arr[7]. However, arr only had 7 elements to begin with, so index 7 is out of bounds since the indices begin at 0, with arr[6] being the seventh element.
As for why it doesn't matter, the final element of the array is already swapped when comparing it to the next-to-last element. Or if the array only had 1 element, it is already sorted.

Finding count of all elemets to the right of current element whose value is less than current element in an array in C

I am trying to find an efficient way to find count of all elemets to the right of current element whose value is less than current element in an array in C.
For example:
My array is, R = [2, 4 ,3 ,1]
Then for 2, elements on right of 2 are (4,3,1), among which less than 2 is 1. So the count is 1.
Then for 4, elements on right of 4 are (3,1), among which less than 4 is 3 and 1. So the count is 2.
Then for 3, elements on right of 3 are (1), among which less than 3 is 1. So the count is 1.
Then for 1, Nothing on right of 1 , so nothing is less so count is 0.
So the output array (Containing all the counts) is [ 1,2,1].
How to do it efficiently in C?
I wrote the following code snippet, which seems to be incorrect:
for( i = 0 ; i < size; i++ ) {
index = find_index(R,size,R[i]);
for( j = index+1 ; j < size; j++ ) {
values_to_right[j] = R[j];
}
print_array(values_to_right, size);
printf("\n****************\n");
}
Where as my find_index() and print_array() functions are as follows:
int find_index(int a[], int num_elements, int value)
{
int i;
for (i=0; i<num_elements; i++)
{
if (a[i] == value)
{
return(i); /* it was found */
}
}
return(-1); /* if it was not found */
}
void print_array(int a[], int num_elements)
{
int i;
for(i=0; i<num_elements; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
Any help will be much appreciated.
Check the code below:
#include <stdio.h>
int main(void) {
int a[4] = {2,4,3,1};
int b[4];
int i,sum,k=0,j;
for(i=0;i<4;i++)
{
sum =0;
for(j=i+1;j<4;j++)
{
if(a[j] < a[i])
sum ++;
}
b[k++] = sum;
}
for(i=0;i<k;i++)
printf("%d ",b[i]);
return 0;
}
int i = 0;
// Used as loop index
int currentValue = myArray[currentIndex];
// Holds value at current element
int count = 0;
// Will hold How many elements have smaller values (your question)
for(i = 0; i < currentIndex; i++){
if(myArray[i] < currentValue){
count++;
}
}
Will tell you how many array elements have a smaller value than your reference element. If you want a list of which elements (array indices) satisfy the condition, it gets more complicated...

arranging the numbers with duplicate entries deleted

#include<stdio.h>
int main(){
int a[9],i,j,r,t,min,c=0;
for(r=0;r<9;r++)
scanf("%d",&a[r]);
for (j=0;j<9;j++) {
min=a[j];
for(i=j;i<9;i++) {
if(a[i] < min ) {
c=i;
min=a[i];
}
}
t=a[j];
a[j]=min;
a[c]=t;
}
for(r=0;r<9;r++)
printf("%d",a[r]);
}
This is the code which i have to arrange the numbers entered byt the user in ascending order.
If input is 1 2 3 2 4 1 5 6 3 output is 1 1 2 2 3 3 4 5 6 but i want the output to be 1 2 3 4 5 6 i.e. duplicate entries deleted.Please help me.
If the range of the numbers is given then you can do it by using a boolean array which will store 1 to the corresponding index of the element.
#include <stdio.h>
#include <stdbool.h>
#define NUM_RANGE 10
int main(){
int num;
bool freq[NUM_RANGE + 1] = {0};
for(int r = 0; r < 9; r++){
scanf("%d",&num);
freq[num] = 1;
}
for (int i = 0; i < NUM_RANGE + 1; i++)
if(freq[i])
printf("%d ", i);
}
#include<stdio.h>
int main(){
int a[] = {1, 2, 3, 2, 4, 1, 5, 6, 3};
int n = sizeof(a)/sizeof(*a);
int i, j, t;
for (j=0;j<n-1;j++){
for(i=j+1;i<n;){
if(a[i] == a[j]){
t = a[i];
a[i] = a[--n];
a[n] = t;
continue;
}
if(a[i] < a[j]){
t = a[i];
a[i] = a[j];
a[j] = t;
}
++i;
}
}
for(i=0;i<n;i++)
printf("%d ", a[i]);
return 0;
}
So, this is the procedure you can follow.
You sort your array (as you have already done). Your sorting algorithm has O(n^2) worst-case-running time where n is the number of Elements in your array. If you care about running time, the optimal running time which can be achieved is O(n logn) [MergeSort].
Next, we need to find the duplicates and delete them.
Since you have already ordered them just loop through your array and check that every number a[i] and the next number a[i+1] are different. If they are not, delete it and fill the empty space by moving all the rest of the array one forward.
So:
for(i = 0; i < 9; i++){
if(a[i] == a[i+1]){
deletNumber(i); //deletes number at position i in the array and shifts the
//rest of the array so the empty space is filled.
}
}
void deleteNumber(int i){
int j;
for(j = i; j<8; j++){
a[j] = a[j++];
}
}

Resources