I'm trying to modify selection sort in such a way that it puts the biggest element at the end of the array and then repeats selection sort for n - 1 items until n is 0. My code compiles but the output is still an unsorted array, please help me out!
#include <stdio.h>
void selection_sort(int arr[], int n);
int main ()
{
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
selection_sort(arr, n);
for(int i = 0; i < n; i++)
printf("%d\n", arr[i]);
return 0;
}
void selection_sort(int arr[], int n)
{
if(n <= 0)
return;
while(n > 0)
{
int max = 0;
int temp, x;
for(int i = 0; i < n; i++)
{
if(arr[i] >= max)
max = arr[i];
x = i;
}
temp = arr[n - 1];
arr[n - 1] = max;
arr[x] = temp;
selection_sort(arr, --n);
}
}
The part
if(arr[i] >= max)
max = arr[i];
x = i;
is wrong. You forgot to write {}, so x = i; is executed unconditionally and the swapping after the loop will always be done with the last element. This means that the swapping is done between the same element and it is effectively doing nothing.
Also note that doing both of loop while(n > 0) and recursion selection_sort(arr, --n); is wasteful. You will need only one of that.
Another note is initializing max with 0 will make it behave wrongly when all elements of the input array are negative.
Finally, you should format your code properly with consistent indentation.
Try this:
void selection_sort(int arr[], int n)
{
if(n <= 0)
return;
while(n > 0)
{
int max = arr[0];
int temp, x;
for(int i = 0; i < n; i++)
{
if(arr[i] >= max)
{
max = arr[i];
x = i;
}
}
temp = arr[n - 1];
arr[n - 1] = max;
arr[x] = temp;
--n;
}
}
Related
So as the question says i am just trying to sort an array with duplicate values.
The array is sorted properly but problem arises when a duplicate value is given to the array
O/P:without duplicate
Enter the size of the array : 5
Enter the 5 elements
7 3 4 8 1
After sorting: 1 3 4 7 8
Original array value 7 3 4 8 1
O/P: with duplicates
5 3 1 1 4
After sorting: 1 3 4 1 3
Original array value 5 3 1 1 4
#include <stdio.h>
void print_sort(int *arr, int size) //function definition
{
int i, j, k, temp, largest = arr[0], smallest = arr[0];
for( i = 1 ; i < size ; i++ )
{
if(arr[i] > largest)
{
largest = arr[i];
}
if(arr[i] < smallest)
{
smallest = arr[i];
}
}
printf("After sorting: ");
for(i = 0; i < size; i++)
{
temp = largest;
printf("%d ", smallest);
for(k = i + 1; k < size; k++)
{
if(arr[i] == arr[k])
{
smallest = arr[i];
break;
}
for(j = 0; j < size; j++)
{
if(arr[j] > smallest && arr[j] < temp)
{
temp = arr[j];
}
}
smallest = temp;
}
}
printf("\n");
printf("Original array value ");
for( i = 0 ; i < size ; i++ )
{
printf("%d ", arr[i]);
}
}
int main()
{
int size, i;
printf("Enter the size of the array : ");
scanf("%d", &size);
int arr[size];
printf("Enter the %d elements\n",size);
for (i = 0; i < size; i++)
{
scanf("%d", &arr[i]);
}
print_sort(arr, size);
}
I understand that it is a specific exercise (homework ?), with no possibility to modify the array not to use an additional array.
This implies that classical sorting algorithms cannot work.
Iteratively searching for the minimum is a possible solution, even if not efficient O(n^2).
To cope with duplicates, it it necessary not only to memorize the current minimum, but also its position.
This is a possible implementation.
#include <stdio.h>
#include <stdlib.h>
void print_sort(int *arr, int size) //function definition
{
int i, j, k, largest = arr[0], smallest = arr[0];
int i_smallest = 0;
for (i = 1; i < size; i++ ) {
if (arr[i] > largest) {
largest = arr[i];
}
if(arr[i] < smallest) {
smallest = arr[i];
i_smallest = i;
}
}
printf("After sorting: ");
for (i = 0; i < size; i++) {
int temp = largest + 1;
int i_temp = -1;
printf("%d ", smallest);
if (i == size-1) break;
for (k = 0; k < size; k++) {
if (arr[k] < smallest) continue;
if (arr[k] == smallest) {
if (k <= i_smallest) continue;
i_temp = k;
temp = smallest;
break;
}
if (arr[k] < temp) {
temp = arr[k];
i_temp = k;
}
}
smallest = temp;
i_smallest = i_temp;
}
printf("\n");
printf("Original array value ");
for( i = 0 ; i < size ; i++ )
{
printf("%d ",arr[i]);
}
}
int main(void) {
int size, i;
printf("Enter the size of the array : ");
if (scanf("%d", &size) != 1) exit(1);
int arr[size];
printf("Enter the %d elements\n",size);
for (i = 0; i < size; i++) {
if (scanf("%d", &arr[i]) != 1) exit(1);
}
print_sort(arr, size);
return 0;
}
Maybe it is easier to insert each read value directly into the sorted Array. So you don't have to sort the array afterwards.
If you want to do it this way, geeksforgeeks.org has nice examples also for C which I already used (https://www.geeksforgeeks.org/search-insert-and-delete-in-a-sorted-array/).
// C program to implement insert operation in
// an sorted array.
#include <stdio.h>
// Inserts a key in arr[] of given capacity. n is current
// size of arr[]. This function returns n+1 if insertion
// is successful, else n.
int insertSorted(int arr[], int n, int key, int capacity)
{
// Cannot insert more elements if n is already
// more than or equal to capacity
if (n >= capacity)
return n;
int i;
for (i = n - 1; (i >= 0 && arr[i] > key); i--)
arr[i + 1] = arr[i];
arr[i + 1] = key;
return (n + 1);
}
/* Driver program to test above function */
int main()
{
int arr[20] = { 12, 16, 20, 40, 50, 70 };
int capacity = sizeof(arr) / sizeof(arr[0]);
int n = 6;
int i, key = 26;
printf("\nBefore Insertion: ");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
// Inserting key
n = insertSorted(arr, n, key, capacity);
printf("\nAfter Insertion: ");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}
So im working on this program that is supposed to take the pointer to an array and the array’s size (number of elements in the array)
as arguments, finds the place the index of the outlier, fixes the array in place (that is puts the outlier to a
place it is supposed to be), and returns the old index where the outlier was found. i finished my code but for some reason, somewhere in my main function its telling me there is a segmentation fault, i know its in my main function because it compiled and ran fine when it was just the original code. heres the code;
#include <stdio.h>
long long int fix_sorted_array(double* arr, unsigned long n)
{
double temp;
int i, j;
for ( i = 0; i < n - 1; i ++)
{
if (arr[i] > arr[i + 1])
{
for ( j = i + 1; j > 0; j --)
{
if (arr[j] < arr[j-1])
{
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
return i + 1;
}
}
return -1;
}
int main()
{
int n;
int j;//declared variables
double arr[n];
printf("Enter elements of array : \n");
for ( int i = 0; i < n; i ++)
{
scanf("%lf", &arr[i]);
}
printf("Return index : %lld\n",fix_sorted_array (&arr[n], n));
printf("Array after : \n");
for ( j = 0; j < n; j ++)
{
printf("%.2lf", arr[j]);
}
}
You're passing an address outside the array to the function in this line:
printf("Return index : %lld\n",fix_sorted_array (&arr[n], n));
You want to pass the address of the start of the array, not the end, so it should be:
printf("Return index : %lld\n",fix_sorted_array (arr, n));
You also need to initialize n before you declare the array.
printf("How many numbers? ");
scanf("%d", &n);
double arr[n];
You have never accepted the value of n. Below code might help.
#include <stdio.h>
long long int fix_sorted_array(double* arr, unsigned long n)
{
double temp;
int i, j;
for ( i = 0; i < n - 1; i ++)
{
if (arr[i] > arr[i + 1])
{
for ( j = i + 1; j > 0; j --)
{
if (arr[j] < arr[j-1])
{
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
return i + 1;
}
}
return -1;
}
int main()
{
int n;
int j;//declared variables
printf("Enter the number of elements in arrays");
scanf("%d",&n); // initialize the values of n
double arr[n];
printf("Enter elements of array : \n");
for ( int i = 0; i < n; i ++)
{
scanf("%lf", &arr[i]);
}
printf("Return index : %lld\n",fix_sorted_array (&arr[0], n)); // Also pass the value of starting index in array i.e. `arr[0]`
printf("Array after : \n");
for ( j = 0; j < n; j ++)
{
printf("%.2lf", arr[j]);
}
}
I have implemented a Counting Sort in an assignment given to us by a teacher but sometimes it doesn't work for large arrays.
Here is the code:
void countingSort(int *t, int n) {
int min = findMin(t, n);
int max = findMax(t, n);
int range = max - min + 1;
int *count, *output;
int i;
count = (int *)malloc(range * sizeof(int));
output = (int *)malloc(n * sizeof(int));
for (i = 0; i < range; i++) {
count[i] = 0;
}
for (i = 0; i < n; i++) {
count[t[i] - min]++;
}
for (i = 1; i < range; i++) {
count[i] += count[i - 1];
}
for (i = n - 1; i >= 0; i--) {
output[count[t[i] - min] - 1] = t[i];
count[t[i] - min]--;
}
for (i = 0; i < n; i++) {
t[i] = output[i];
}
}
What's wrong with my code?
Your code seems to work for small values of range, but might fail if min and max are too far apart, causing the computation of range to overflow the range of int and malloc() to fail.
You should check for overflow in range and check memory allocation success. Note too that calloc() is more appropriate than malloc() for the count array. Finally, you must free the allocated arrays.
Here is a modified version:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int findMax(const int *t, int n) {
int max = INT_MIN;
while (n-- > 0) {
if (max < *t) max = *t;
t++;
}
return max;
}
int findMin(const int *t, int n) {
int min = INT_MAX;
while (n-- > 0) {
if (min > *t) min = *t;
t++;
}
return min;
}
int countingSort(int *t, int n) {
int min, max, range, i;
int *count, *output;
if (n <= 0)
return 0;
min = findMin(t, n);
max = findMax(t, n);
if (min < 0 && max >= 0 && (unsigned)max + (unsigned)(-min) >= INT_MAX) {
fprintf(stderr, "countingSort: value range too large: %d..%d\n", min, max);
return -1;
}
range = max - min + 1;
if ((count = (int *)calloc(range, sizeof(int))) == NULL) {
fprintf(stderr, "countingSort: cannot allocate %d element count array\n", range);
return -1;
}
if ((output = (int *)malloc(n * sizeof(int))) == NULL) {
fprintf(stderr, "countingSort: cannot allocate %d element output array\n", n);
free(count);
return -1;
}
for (i = 0; i < n; i++) {
count[t[i] - min]++;
}
for (i = 1; i < range; i++) {
count[i] += count[i - 1];
}
for (i = n; i-- > 0;) {
output[count[t[i] - min] - 1] = t[i];
count[t[i] - min]--;
}
for (i = 0; i < n; i++) {
t[i] = output[i];
}
free(count);
free(output);
return 0;
}
You can avoid the cumbersome and potentially inefficient downward loop by replacing the second and third for loops with this:
/* compute the first index for each value */
int index = 0;
for (i = 0; i < range; i++) {
incr = count[i];
count[i] = index;
index += incr;
}
/* copy each value at the corresponding index and update it */
for (i = 0; i < n; i++) {
output[count[t[i] - min]++] = t[i];
}
Is there a way to square the elements of the array with time complexity of O(n)?
I tried two ways of doing it but I think they are both O(N^2)
PS: I can't use "*", only addition/subtraction.
1.
#include <stdio.h>
int squr(int n, int j){
if(j == 0)
return 0;
else if(j > 0)
return(n + squr(n, j - 1));
else if (n < 0)
return(n + squr(n, j - 1));
}
void loop(int* arr, int count){
for(int n = 0; n < count; n++)
arr[n] = squr(arr[n], arr[n]);
}
2.
void squr(int* arr, int N){
for(int i = 0; i < N; i++){
for(int j = 0; j < i; j++)
sum += i;
arr[i] = sum;
sum = 0;
}
}
Although not likely what OP had in mind, code can use the size of a computed pointer. No *. Of course restricted to n > 0.
int foo(int n, char a[1][n][n]) {
return sizeof a[0];
}
int main(void) {
printf("%d\n", foo(5, 0));
printf("%d\n", foo(100, 0));
return 0;
}
Output
25
10000
I want to find index of max value in array in C.
I write this code example:
maks=0;
for(i=0;i< N * N;i++) {
if(array[i]>maks) {
maks=(int) array[i];
k=i;
}
}
But this isn't work properly.Could you advise me another example please?
Best Regards...
k = 0;
max = array[k];
for (i = 0; i < N * N; ++i)
{
if (array[i] > max)
{
max = (int)array[i];
k = i;
}
}
Should work !
Below function accepts pointer to array with size of the array as arguments and returns the max index.
int max_index(float *a, int n)
{
if(n <= 0) return -1;
int i, max_i = 0;
float max = a[0];
for(i = 1; i < n; ++i){
if(a[i] > max){
max = a[i];
max_i = i;
}
}
return max_i;
}
Usage example,
float a[3] ={1.2,3.2,4.0};
cout<<max_index(a,3)<<endl; //will output 2, because a[2] element is the max