I'm trying to sort an array using this function findMinimumIndex in a for loop, but I can't seem find where it's not sorting correctly. Any suggestions? The function itself works fine, but when I try to use it in a loop, it doesn't work. Any suggestions? Thanks!
int findMinimumIndex(A[], int a, int b); //Finds smallest index of portion of array (A[i] ... A[j])
int main(){
int A[5] = {4,6,7,4,3};
int smallest_index;
for (int j = 0; j < count; j++){
smallest_index = findMinimumIndex(A, j, 4);
printf("Sorted: %d\n", A[smallest_index]);
}
}
int findMinimumIndex(int A[], int a, int b){
int smallest_value = A[a];
int index = 0;
for (int k = a; k < j - 1; k++){
if (A[k + 1] < smallest_value){
smallest_value = A[k+1];
index = k + 1;
}
}
return index;
}
If you find the minimum value and its index, you should switch values:
Look at this example:
You have got array:
{4,6,7,4,3}
At first, you will find value 3 at index 4, but you have to move the smallest value (switch with value on j=0 index):
{3,6,7,4,4}
Then you will find 4 on index 3, then, switch it with j=1:
{3,4,7,6,4}
etc.
Modification of your code:
for (int j = 0; j < count; j++){
smallest_index = findMinimumIndex(A, j, 4);
int tmp = A[smallest_index];
A[smallest_index] = A[j];
A[j] = tmp;
printf("Sorted: %d\n", A[j]);
}
EDIT: correction:
length of the array is 5:
smallest_index = findMinimumIndex(A, j, 5);
and index should be set to a
int findMinimumIndex(int A[], int a, int b){
int smallest_value = A[a];
int index = a;
/* code */
}
Related
I am trying to implement the Selection Sort Algorithm and here is my attempt:
int select(int arr[], int i)
{
int j, minIndex;
minIndex = i;
for (j = i + 1; arr[j]; j++)
{
if (arr[j] < arr[minIndex])
minIndex = j;
}
return minIndex;
}
void selectionSort(int arr[], int n)
{
int i, iMin;
for (i = 0; i < n - 1; i++)
{
iMin = select(arr, i);
if (iMin != i)
{
int temp = arr[i];
arr[i] = arr[iMin];
arr[iMin] = temp;
}
}
}
Even though my code works fine, if there is an element in the array with value zero it fails. Here is an example case:
4 1 3 9 0
Output:
1 3 4 9 0
I know that my logic is correct, because it works with other cases, but why is it failing if there is a 0 in the array element?
Your loop condition is wrong:
for (j = i + 1; arr[j]; j++)
instead of arr[j] you need j < n.
Renamed select() to selectMin() to avoid conflict with existing function with that name. If you specify the length n before the array arr your can document how the two are related with current compilers.
Extracted the swap() function.
Minimized scope of variables.
size_t instead of int for indices as they are non-negative. The type difference also helps you distinguish between the indices of the array (size_t) the values of the array (int) which was the root cause of your troubles.
Hard-coded your test case and implemented a print() functions to verify correct result.
#include <stdio.h>
#include <stdlib.h>
void print(size_t n, int a[n]) {
for(size_t i = 0; i < n; i++)
printf("%d%s", a[i], i + 1 < n ? ", " : "\n");
}
size_t selectMin(size_t n, int arr[n], int i) {
size_t minIndex = i;
for (size_t j = i + 1; j < n; j++)
if (arr[j] < arr[minIndex])
minIndex = j;
return minIndex;
}
void selectionSort(size_t n, int arr[n]) {
for (size_t i = 0; i < n - 1; i++) {
size_t iMin = selectMin(n, arr, i);
if (iMin != i)
swap(arr + i, arr + iMin);
}
}
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main(void) {
int a[] = {4, 1, 3, 9, 0};
selectionSort(sizeof a / sizeof *a, a);
print(sizeof a / sizeof *a, a);
}
and the output is:
0, 1, 3, 4, 9
The loop
for (j = i + 1; arr[j]; j++)
is problematic because of the loop condition arr[j]. As a condition it's equivalent to arr[j] != 0. C doesn't have any concept of "null values" like e.g. C# or Java.
You need to pass the array length to the select function, you can't rely on the array data itself to know when and where the array ends.
Using the array data itself will either lead to premature loop end if the data contains zeros. Or will go out of bounds if the array data doesn't contain any zeros.
Im trying to learn C and I'm doing this program to sort an array but It doesn't work and I'm not sure why, I tested each function and works well, someone knows if its a problem of variables or something?
#include <stdio.h>
#include <stdlib.h>
#define N 5
int V[5] = { -383, 386, 277, 415, 293 };
void displayArray(int arr[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("%d ", arr[i]);
}
int maxim(int v[], int n)
{
int i, m;
m = v[0];
/*
Find maxim element
*/
for (i = 1; i < n; i++)
if (v[i] > m)
m = v[i];
/*
Search element position
*/
for (i = 0; i < N; i++)
if (v[i] == m)
return i;
}
void sort(int v[], int n)
{
int i, pos, t;
for (i = 0; i < n; i++)
pos = maxim(v, n - i);
/*
Swap elements
*/
t = v[n - 1 - i];
v[n - 1 - i] = v[pos];
v[pos] = t;
}
int main()
{
displayArray(V, N);
sort(V, N);
printf("\n");
displayArray(V, N);
return 0;
}
The output is
-383 386 277 415 293 - Original Array
21900 386 277 415 293 - 'Sorted' Array
First fix your maxim function. Its purpose is to find the maximum index of a sequence v of magnitude n. Therefore, remembering the maximum value in m is irrelevant; you want to remember where it resides :
int maxim(int v[], int n)
{
int m=0;
for (int i=1; i<n; ++i)
{
if (v[m] < v[i])
m = i; // save new max location
}
return m;
}
After that, the sort, which is completely wrong. This:
int i, pos, t;
for (i = 0; i < n; i++)
pos = maxim(v, n - i);
is pointless. It calculates, and overwrites, pos repeatedly until the last iteration, which is the only one that is processed with:
t = v[n - 1 - i];
v[n - 1 - i] = v[pos];
v[pos] = t;
E..g, you sort one element, and then exit your sort. You need to sort them all, starting with the full segment, then reducing the size of the segment by one with each iteration after you swap the most-maximum element into position for that segment.
void sort(int v[], int n)
{
for (int i=0; i<(n-1); ++i)
{
int m = maxim(v, (n-i)); // max of this segment
int tmp = v[m];
v[m] = v[n-i-1];
v[n-i-1] = tmp;
}
}
Your program is inefficient, but almost correct. The only place where you must focus is:
void sort(int v[], int n)
{
int i, pos, t;
for (i = 0; i < n; i++)
pos = maxim(v, n - i);
/*
Swap elements
*/
t = v[n - 1 - i];
v[n - 1 - i] = v[pos];
v[pos] = t;
}
Well, C is not Python, so if, after getting pos you want to swap the elements of your array, then you need to group all of the for loop in braces, as in:
void sort(int v[], int n)
{
int i, pos, t;
for (i = 0; i < n; i++) {
pos = maxim(v, n - i);
/*
Swap elements
*/
t = v[n - 1 - i];
v[n - 1 - i] = v[pos];
v[pos] = t;
}
}
pos = maxim(v, n - i);
should be
pos = maxim(v, n);
I wanted to find the sum of each row and then sort it. I managed to do this but to make it more complicated I decided to find from which row the min sum and the max sum was originated.
Example: The row with the min sum is the 3rd and the row with the max sum is is the 5th.
The main issue in my approach that I attempted was that the b[] array (in the sortfunction below) which I used to store the initial sum of each row is now replaced with the sorted values and I cannot work with the unsorted values which would show the rows that are needed.
#include<stdio.h>
#define ROWS 5
#define COLS 3
void printnumbers(int arr[][COLS]);
void sortfunction(int arr[][COLS]);
int main() {
int arr[ROWS][COLS] = {{1, 2, 3},
{2, 3, 4},
{3, 1, 1},
{5, 5, 6},
{35, 335, 6}};
printnumbers(arr);
sortfunction(arr);
return 0;
}
void printnumbers(int arr[][COLS]){
int i,j;
for(i = 0; i<ROWS; i++)
{
printf("\n");
for(j = 0; j<COLS; j++)
{
printf("%d\t", arr[i][j]);
}
}
}
//swap function below
void swap(int* xp, int* yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// sort function
void sortfunction(int arr[][COLS]) {
int i, j, total, k, b[ROWS];
k = 0;
printf("\n");
for (i = 0; i < ROWS; i++) {
total = 0;
for (j = 0; j < COLS; j++) {
total += arr[i][j];
}
if (j == COLS) {
b[k] = total;
k += 1;
}
}
for (k = 0; k < ROWS; k++) {
printf("the sum of the %dst row is %d\n", k + 1, b[k]);
}
int a, q, min_idx;
int n = sizeof(b) / sizeof(b[0]);
// One by one move boundary of unsorted subarray
for (q = 0; q < n - 1; q++) {
// Find the minimum element in unsorted array
min_idx = q;
for (a = q + 1; a < n; a++)
if (b[a] < b[min_idx])
min_idx = a;
// Swap the found minimum element
// with the first element
swap(&b[min_idx], &b[q]);
}
for (i = 0; i < n; i++)
printf("%d ", b[i]);
printf("\n");
//Now I want to find which row has the least sum and which has the max sum but the b[] array is already sorted.
}
This prints:
the sum of the 1st row is 6
the sum of the 2st row is 9
the sum of the 3st row is 5
the sum of the 4st row is 16
the sum of the 5st row is 376
5 6 9 16 376 //it got sorted
and it needs to print also this:
The row with the min sum is in the 3rd row
The row with the max sum us un the 5th row.
One solution would be to make b an array of a struct with the sum and row numbers. The swap() and sortfunction() functions would then be as follows (including some minor simplifications):
typedef struct
{
int sum;
int row;
} tRowSum;
//swap function below
void swap(tRowSum* xp, tRowSum* yp)
{
tRowSum temp = *xp;
*xp = *yp;
*yp = temp;
}
// sort function
void sortfunction(int arr[][COLS]) {
int i, j, total;
tRowSum b[ROWS];
printf("\n");
for (i = 0; i < ROWS; i++) {
total = 0;
for (j = 0; j < COLS; j++) {
total += arr[i][j];
}
b[i].sum = total;
b[i].row = i;
}
for (i = 0; i < ROWS; i++) {
printf("the sum of the %dst row is %d\n", i + 1, b[i].sum);
}
int a, q, min_idx;
// One by one move boundary of unsorted subarray
for (q = 0; q < ROWS - 1; q++) {
// Find the minimum element in unsorted array
min_idx = q;
for (a = q + 1; a < ROWS; a++)
if (b[a].sum < b[min_idx].sum)
min_idx = a;
// Swap the found minimum element
// with the first element
swap(&b[min_idx], &b[q]);
}
for (i = 0; i < ROWS; i++) {
printf("%d (%d)", b[i].sum, b[i].row);
printf("\n");
}
}
After sorting b with respect to the sum, the original row numbers are then available for each entry.
So I try to do the Heap Sort in C for a row of an 2d array
So basically I find the smallest sum of all the rows from the array and I try to sort the elements of that row, for that I'm trying to store the index of the smallest row with a pointer but when I use pointer the programm it's not returning the index but the adress
//funcion to find the smallest row sum
void min_rand(int(*a)[50], int n, int m, int *mi)
{
int min_row = 0;
int i, j;
for (j = 0; j < m; j++)
min_row += a[0][j];
for (i = 0; i < n; i++) {
int sum_row = 0;
for (j = 0; j < m; j++)
sum_row += a[i][j];
if (sum_row < min_row) {
min_row = sum_row;
*mi = i;
}
}
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void heapify_c(int(*a)[50], int n, int i, int mi)
{
int largest = i;
int l = 2 *i + 1;
int r = 2 *i + 2;
if (l < n && a[mi][l] > a[mi][largest])
largest = l;
if (r < n && a[mi][r] > a[mi][largest])
largest = r;
if (largest != i) {
swap(&a[mi][i], &a[mi][largest]);
heapify_c(a, n, largest, mi);
}
}
void heapSort_c(int(*a)[50], int n, int mi)
{
for (int i = n / 2 - 1; i >= 0; i--)
heapify_c(a, n, i, mi);
for (int i = n - 1; i > 0; i--) {
swap(&a[mi][0], &a[mi][i]);
heapify_c(a, i, 0, mi);
}
}
int main()
{
int a[50][50];
int n, m, mi;
min_rand(a, n, m, &mi);
heapSort_c(a, n, mi);
return 0;
}
I don't print the sorted elements in the e.g. above but I just want to know if I'm doing something so terrebly wrong cause I did this before with counting sort and it worked without any problems
I'm currently trying to learn C, and the exercise I found online has me creating a function that returns the index of the smallest value in an array. This is my function:
int return_index_of_minimum(int A[10], int i, int j){
int minimum_value = A[i];
int index_to_return = 0;
for (int index = i; index < j; index++){
if (A[index] < minimum_value){
minimum_value = A[index];
index_to_return = index;
}
}
return index_to_return;
}
i and j are the lower and upper bound numbers the function should look in. For example, if i is 4 and j is 8, that means the function will return the index of the smallest value between indices 4 and 8.
Here is my main function:
#include <stdio.h>
int main(){
int numbers[10];
int user_input = 0;
for (int i = 0; i < 10; i++){
printf("Please enter a number: ");
scanf_s("%d", &user_input);
numbers[i] = user_input;
}
for (int i = 0; i < 10; i++){
int index_of_min_value = return_index_of_minimum(numbers, i, 10);
int old_num = numbers[index_of_min_value];
int new_num = numbers[i];
numbers[index_of_min_value] = new_num;
new_array[i] = old_num;
}
for (int i = 0; i < 10; i++){
printf("%d\n", new_array[i]);
}
}
The user would first enter a bunch of numbers and that would populate the array with the user's values. The idea is to use return_index_of_minimum to return the index of the smallest item in an array, and then set that equal to numbers[0] with a for loop, and then numbers[1], and then so on. old_num is the lowest number in the array, at its previous index. Here, I'm trying to swap that minimum value with whatever is at numbers[i] However, when I'm done sorting through the entire array, and am printing it out, I see that 10 (when the user enters 1-10 randomly for values) is at index 0, and then the rest of the numbers are in order. Does anybody see what is wrong here?
Here is a fix:
int return_index_of_minimum(int A[10], int i, int j){
int minimum_value = A[i];
int index_to_return = i;
...
}
Unfortunately this code doesn't have protection of invalid arguments, but otherwise this is an answer you've been looking for.
The reason is in call index_of_minimum(a, 9, 10): the loop performs only one iteration for index = 9, and because the minimum value is already initialized to value a[9], the index_to_return is not updated due to condition check.
This is a different approach that doesn't have same issue:
int return_index_of_minimum(int A[10], int i, int j){
/* assuming i < j */
int minimum_value = A[i];
int index_to_return = i; /* First element is a candidate */
for (int index = i + 1; index < j; index++){
/* Iterate from second element */
if (A[index] < minimum_value){
minimum_value = A[index];
index_to_return = index;
}
}
return index_to_return;
}
I believe there is an error in your return_index_of_minimum function.
int index_to_return = 0;
The problem lies I think here as the value of index_to_return will stay 0 if you call return_index_of_minimum(numbers, 5, 10); and that numbers[5] if the actual minimum.
However why not use a simple bubble-sort like the one implemented here
/*
* C program to sort N numbers in ascending order using Bubble sort
* and print both the given and the sorted array
*/
#include <stdio.h>
#define MAXSIZE 10
int main(void)
{
int array[MAXSIZE];
int i, j, num, temp;
printf("Enter the value of num \n");
scanf("%d", &num);
printf("Enter the elements one by one \n");
for (i = 0; i < num; i++)
{
scanf("%d", &array[i]);
}
printf("Input array is \n");
for (i = 0; i < num; i++)
{
printf("%d\n", array[i]);
}
/* Bubble sorting begins */
for (i = 0; i < num; i++)
{
for (j = 0; j < (num - i - 1); j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
printf("Sorted array is...\n");
for (i = 0; i < num; i++)
{
printf("%d\n", array[i]);
}
}