My selection sort is very weird (code in C) - 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.

Related

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.

Maximum value of every contiguous subarray

Given an unsorted array A[0...n-1] of integers and an integer k; the desired algorithm in C should calculate the maximum value of every contiguous subarray of size k. For instance, if A = [8,5,10,7,9,4,15,12,90,13] and k=4, then findKMax(A,4,10) returns 10 10 10 15 15 90 90.
My goal is to implement the algorithm as a C programm that reads the elements of A, reads k and then prints the result of the function findKMax(A,4,10). An input/output example is illustrated bellow (input is typeset in bold):
Elements of A: 8 5 10 7 9 4 15 12 90 13 end
Type k: 4
Results: 10 10 10 15 15 90 90
What I've tried so far? Please keep in mind that I am an absolute beginner in C. Here is my code:
#include <stdio.h>
void findKMax(int A[], int k, int n) {
int j;
int max;
for (int i = 0; i <= n-k; i++) {
max = A[i];
for (j = 1; j < k; j++) {
if (A[i+j] > max)
max = A[i+j];
}
}
}
int main() {
int n = sizeof(A);
int k = 4;
printf("Elements of A: ");
scanf("%d", &A[i]);
printf("Type k: %d", k);
printf("Results: %d", &max);
return 0;
}
Update March 17th:
I've modified the source code, i.e. I've tried to implement the hints of Michael Burr and Priyansh Goel. Here is my result:
#include <stdio.h>
// Returning the largest value in subarray of size k.
void findKMax(int A[], int k, int n) {
int j;
int largestValueOfSubarray;
for (int i = 0; i <= n-k; i++) {
largestValueOfSubarray = A[i];
for (j = 1; j < k; j++) {
if (A[i+j] > largestValueOfSubarray)
largestValueOfSubarray = A[i+j];
}
printf("Type k: %d", k);
}
return largestValueOfSubarray;
}
int main() {
int n = 10;
int A[n];
// Reading values into array A.
for (int i = 0; i < n; i++) {
printf("Enter the %d-th element of the array A: \n", i);
scanf("%d", &A[i]);
}
// Printing of all values of array A.
for (int i = 0; i < n; i++) {
printf("\nA[%d] = %d", i, A[i]);
}
printf("\n\n");
// Returning the largest value in array A.
int largestValue = A[0];
for (int i = 0; i < n; i++) {
if (A[i] > largestValue) {
largestValue = A[i];
}
}
printf("The largest value in the array A is %d. \n", largestValue);
return 0;
}
I guess there is not so much to code. Can anybody give me a hint how to do the rest. I need an advice how to "combine" the pieces of code into a running program.
Since you are a beginner, lets begin with the simplest algorithm.
for every i, you need to find sum of k continous numbers starting from that i. And then find the max of it.
Before that you need to see how to take input to an array.
int n;
scanf("%d",&n);
int a[n];
for(int i = 0; i < n; i++) {
scanf("%d",&a[i]);
}
Also, you will need to call the function findKMax(a,n,k);
In your findKMax function, you have to implement the algorithm that I mentioned.
I will not provide the code so that you may try on your own. If you face any issue, do tell me.
HINT : You need to use nested loops.
You find max value in window many times, but output only the last max value.
The simplest correction - add output in the end of main cycle:
for (int i = 0; i <= n-k; i++) {
max = A[i];
for (j = 1; j < k; j++) {
if (A[i+j] > max)
max = A[i+j];
}
printf("Type k: %d", k);
}
The next step - collect all local max values in a single string "10 10 10 15 15 90 90" or additional array of length n-k+1: [10,10,10,15,15,90,90] and print it after the main cycle (I don't know the best approach for this in C)

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

Transferring sorting loop results to another array

Here's a loop to sort an array from min to max, I need the result of this loop to be put into another array so I can filter and remove the numbers that occur only once and find the last member of what's left.
Here's the code I have so far:
#include<stdio.h>
#include<conio.h>
#define buffas 1024
void main() {
int arr[buffas],i,j,element,no,temp;
printf("\nEnter the no of Elements: ");
scanf("%d", &no);
for(i=0; i<no; i++) {
printf("\n Enter Element %d: ", i+1);
scanf("%d",&arr[i]);
}
for(i=0; i<no; i++) {
for(j=i; j<no; j++) {
if(arr[i] > arr[j]) {
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
printf("\nSorted array:");
for(i=0; i<no; i++) {
printf("\t%d",arr[i]);
}
getch();
}
How do I change the
printf("\t%d",arr[i]);
To fill another array and then sort that to remove single entries and leave ony those that repeat at least once.
eg. the first aray is
2 2 1 6 9 9
and after the second sorting the result should be
2 2 9 9
#include <stdio.h>
#define buffas 16
int main(void)
{
/* Instead of original input and sorting code */
int arr[] = { 1, 2, 2, 6, 9, 9, 10, 10, 10, 11, 12, 13, 14 };
int no = sizeof(arr) / sizeof(arr[0]);
/* Code to copy only duplicated elements in arr */
int copy[buffas];
int n = 0;
for (int i = 0; i < no; i++)
{
int j;
for (j = i + 1; j < no; j++)
{
if (arr[i] != arr[j])
break;
}
if (j - i > 1)
{
for (int k = i; k < j; k++)
copy[n++] = arr[k];
i = j - 1;
}
}
/* Print results for verification */
for (int i = 0; i < n; i++)
printf("c[%d] = %d\n", i, copy[i]);
return 0;
}
The code has been run with various lengths of sorted array and different data in the array; it seems to be correct. The code above produces the output:
c[0] = 2
c[1] = 2
c[2] = 9
c[3] = 9
c[4] = 10
c[5] = 10
c[6] = 10
Note that the code uses the C99 feature of declaring variables in a for loop control statement; if you're on Windows and without C99 support, you'll need to declare i and k outside the loops. If you're using GCC, you need to add -std=c99 or a similar option.

Resources