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.
Related
A question in my book explained selection sort in three lines and then asked the reader to write CODE for it in C. I have written the code here and it is working fine, but I am a little confused whether I have written it in the right way or not. Please read the code, I have even added comments and correct me if needed.
#include <stdio.h>
#define VALUESIZE 10
int main(void)
{
int temp;
int value[VALUESIZE] = {3, 5, 46, 89, 72, 42, 312, 465812, 758, 1};
// Printing array just for the user to see.
for (int k=0; k<VALUESIZE; k++)
{
printf("[");
printf("%d", value[k]);
printf("] ");
}
printf("\n");
// Sorting algo begins
for (int i=0; i < VALUESIZE - 1; i++) // This will obviously loop through each element in our array except the last element as it will automatically be sorted after n-1 steps
{
for (int j= i+1; j <= VALUESIZE; j++) // This nested loop will go through each element which appears after ith element. For e.g. If i = 2, then j will loop through entire array starting from j = 3
{
if (value[i] > value[j]) // This basic if statement will compare our ith and following jth value
{
temp = value[i]; // If the program finds any value[j] greater than value[i], then the values will be swapped.
value[i] = value[j];
value[j] = temp;
}
}
}
// Now after sorting, print the new sorted array.
for (int l=0; l<VALUESIZE; l++)
{
printf("[");
printf("%d", value[l]);
printf("] ");
}
printf("\n");
}
Select sort needs to iterate through the array to compare the ith value. At the end of this pass it will swap the 2 values. This is a reason why its not a very good sort algorithm for medium or large arrays.
I have changed your code a bit below
Untested but should work:
// Sorting algo begins
for (int i = 0; i < arr_length - 1; i++)
{
int min = i;
for (int j = i + 1; j <= arr_length; j++)
{
if (value[j] < value[min])
{
min = j;
}
}
//now swap
int cache = value[min];
value[min] = value[i];
value[i] = cache;
}
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.
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.
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...
#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++];
}
}