Shell Sort C language - c

The task was simply to write a program to sort the entered (or randomly generated) numbers using the Shell sort method. But then the teacher decided to complicate the task and said:
Create another function that will test Shell's algorithm: create many arrays from n random numbers, sort by Shell's method and display the average number of iterations for all these arrays.
Please, help and explain how to do it
This is my code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shellsort(int v[], int n);
int main() {
srand(time(NULL));
int N;
printf("Input N: ");
scanf_s("%d", &N);
int *a = (int *)malloc(N * sizeof(int));
int i = 0;
printf("Enter masiv: ");
for (; i < N; i++) {
a[i] = rand() % 100;
printf("%d ", a[i]);
}
shellsort(a, N);
printf("\n");
printf("Result: ");
for (i = 0; i < N; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
void shellsort(int v[], int n) {
int i, j, gap, temp;
int num = 0;
for (gap = n / 2; gap > 0; gap /= 2) {
for (i = gap; i < n; i++)
for (j = i - gap; j >= 0 && v[j] > v[j + gap]; j -= gap) {
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
num++;
}
}
printf("\n");
printf("Number of iterations: %d\n", num);
}
Many thanks in advance to everyone who responds;))

Alright, I will start by saying that I am not gonna do your homework and write the code for it. I'll just try to give you a starting point.
Shell sort currently doesn't compute the number of iterations, so you might declare a variable named iterations at the beginning of shellsort and increment it in the deepest loop inside shell sort, and return this variable instead of returning void.
The new function that you're about to write should be similar to what you're doing in the main for the number generation part.
Make a loop that encapsulates the loop that generates arrays for you. Because you need multiple arrays now.
Store the sum of iterations, maybe like this sum += shellsort(a);
Then the average of iterations is the sum/N, where N is the number of random arrays you want to generate.

Related

How to show random numbers in descending order in array

I want to generate numbers from 1 to 10 in an array, then print them in descending order. The method I’ve used so far doesn’t work properly. Sometimes the number 10 is at the bottom, and all other numbers are correctly ordered.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int a[7], j, i;
srand(time(NULL));
a[0] = rand() % 10;
int length = 7;
for(int i = 0; i < 7; i++) {
int duplikat = 0;
a[i] = rand() % 10+1;
for (int j=0; j<i; j++) {
// descending order: Just change (a[j] > a[j+1])
if(a[i] == a[j]) duplikat = 1;
if (a[j] < a[j+1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
if (duplikat) i--;
}
}
for(int i = 0; i< length; i++) {
printf("a[%d] = %d\n", i, a[i]);
}
printf("\n");
for(j=0;j<7;j++) printf("\n%d ", a[j]);
return 0;
}
Some observations:
The line if (duplikat) i--; should be outside the inner loop over j, so that you decrease i at most once when a dupicate is found.
Fiddling with the index of a for loop to implement some skipping logic is also very brittle. Instead, consider a while loop until your array a is full where you add items only if they are no duplicates.
If you want to "bubble down" the new number so that the part of the array is sorted, you must start from the right-hand side of the array. Otherwise, the only swap that may take place is of the new item with the last item in the array.
You could do something similar to insertion sort, where you keep the generated array sorted at all times:
Determine a new random number to add, the "pick".
Find the place i where the pick goes; if the number was already generated, pick again.
Otherwise, create an empty slot at the end of the array by incrementing the actual length, then move all elements right of the i one place to the right. There is now a gap at i, where you place your pick.
Repeat until your array has enough items.
In code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int a[7];
int length = 7; // desired length of array
int n = 0; // current length of array
srand(time(NULL));
while (n < length) {
int pick = rand() % 10 + 1;
int i = 0;
// skip greater elements
while (i < n && pick < a[i]) i++;
// shift smaller elements and add pick if it is unique
if (i == n || pick != a[i]) {
int j = n++;
while (i < j) {
a[j] = a[j - 1];
j--;
}
a[i] = pick;
}
}
// print array
for (int i = 0; i< length; i++) {
if (i) printf(", ");
printf("%d", a[i]);
}
printf("\n");
return 0;
}

Beginner in C - Programming arithmetic algorithm?

Here is what I'm supposed to do:
Write a program that reads a positive integer and displays the maximum positive integer n for which the sum 1^2 + 2^2 + 3^2 + ... + n^2 is less than the given number.
So far I am only able to just add the sum of all natural numbers until n:
#include <stdio.h>
int main ()
{
unsigned int n;
int sum = 0;
int i;
sum = 0;
printf("Print your number");
scanf("%d", &n);
for (i = 1; i <= n; ++i)
{
sum += i;
}
printf("sum = %d", sum);
return 0;
}
Appreciate the help!
you can try this
#include <stdio.h>
int max_positive_integer(int given_number)
{
int sum = 0;
int n = 1;
while (sum < given_number) {
sum += n * n;
n++;
}
printf("sum= %d\n", sum);
return n;
}
int main ()
{
printf("Print your number:");
int n;
scanf("%d", &n);
int max_integer = max_positive_integer(n);
printf("max_integer = %d\n", max_integer);
return 0;
}
How to sum a series of squares in a loop is the easy part
sum = 0;
for (n=0; TBD; n++) {
sum += n*n;
}
printf(..., n);
The trick is when to stop given "sum ... is less than the given number."
Code could use
for (n=0; sum + n*n < given_number; n++) {
sum += n*n;
}
n--;
That works up to a point, yet seems redundant. It has a problem in that sum + i*i may overflow. Perhaps subtract i*i each time as we do not need to report the sum, just n.
for (n=0; n*n < given_number; n++) {
given_number -= n*n;
}
n--;
What it nice about this is that the compare on the right side gets smaller as n*n increases, yet n*n does not overflow. Note: n will be about the cubic root of given_number
If you want to avoid the loop, research Sum of First n Squares
As #user4581301 commented, use "%u" with unsigned.

sum elements of matrix and calculate the average of the i-th line

Hi all i have a problem with this exercise in Language C.
The exercise is:
Given a matrix write a function that:
A) Calculate and return the sum of the elements.
B) Calculate and return the average of the i-th line
I did my own procedure but i have a lot errors.
My procedure is:
#include <stdio.h>
#include <stdlib.h>
void main(){
int n=10;
int m=10;
int i;
int j;
int mat [i][j];
int sum=0;
for (i=0;i<n;i++){
for (j=0; j<m;j++)
sum=sum+mat[i][j];}
printf("The sum of all elements of matrix is:%d",sum);
somma=0;
for (j=0;j<m;i++){
sum=sum+mat[i][j];
sum=sum/m
printf("The average of i-th line is:%d",sum);
}
}
i think that i have to put scanf somewhere but i don't know where.
I hope that you can help me
thank you!
You declare a matrix with undefined sizes
int mat [i][j];
where i and j are uninitizlized.
You probably want
int mat [n][m];
Moreover your matrix should be inizialized with values, otherwise you'll get the sum of stack garbage.
At the end, a possible solution is
#include <stdio.h>
int main(void)
{
int n = 2;
int m = 2;
int i;
int j;
int mat[n][m];
int sum = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
printf("Insert value of mat[%d][%d]: ", i, j);
scanf("%d", &mat[i][j]);
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
sum = sum + mat[i][j];
}
}
printf("The sum of all elements of matrix is: %d\n", sum);
for (i = 0; i < n; i++)
{
sum = 0;
for (j = 0; j < m; j++)
{
sum = sum + mat[i][j];
}
sum = sum / m;
printf("The average of line %d is: %d\n", i, sum);
}
}
As you can see I changed the average calculation:
First of all you wrote a j loop incrementing i
You must loop for all lines, so you must add a for loop that inc rows
sum must be reset each time you calculate the row average
take notes that the average is calculated using integers, so no decimals will be available.

If entered an even number of integers in bubble sort program a random number is inserted in the middle

I have a task to sort negative and positive numbers while using dynamic memory, therefore in this case I used calloc and bubble sort to arrange negative numbers first while not changing their order. The problem is when I enter an even number of integers, in the middle of the result some random negative number of 10 digits appears. The same doesn't happen with odd number of integers. What seems to be the problem?
#include <stdio.h>
#include <stdlib.h>
#define SIZE 1000
void swap(int *arr, int n) {
int i, j, temp;
for (i = 0; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (arr[j] < 0) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
printf("sorted integers to negative and positive: \n");
for (i = 0; i < n; i++) {
printf("%i ", arr[i]);
}
}
int main() {
int n;
int i, *sk;
printf("Enter integer: \n");
scanf("%d", &n);
printf("Enter %i integers: \n", n);
sk = (int*)calloc(sizeof(int), n);
for (i = 0; i < n; i++) {
scanf("%d", sk + i);
}
swap(sk, n);
return 0;
}
This is undefined behavior that happens to manifest itself to you only when you happen to enter an even number of integers, but in reality the problem is always there: you read a value from one-past-the-end of the array, and it makes its way to the middle of your array.
You can fix this behavior by changing i <= n and j <= n with i < n and j < n. However, this is not going to fix your broken sorting algorithm, because the swapping condition is incorrect as well. Instead of
if(arr[j]<0)
it should be
if(arr[j]<arr[j-1])
You have 2 classic bugs in your for loops:
for (i = 0; i <= n; i++) is almost always wrong because the loop is run n + 1 times, where it should only enumerate index values from 0 to n - 1.
You have the same off by one error in the second loop: the test j <= n makes you go one step too far and read beyond the end of the array. Some random value gets shuffled into the array, but this undefined behavior could have worse consequences.
Furthermore, your comparison test is incorrect, it should be if (arr[j] < arr[j-1]).
As a rule of thumb, whenever you see the <= operator in a loop test, look again, it is probably a bug.
Here is a corrected version:
void swap(int *arr, int n) {
int i, j, temp;
for (i = 0; i < n; i++) {
for (j = 1; j < n; j++) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
printf("sorted integers to negative and positive: \n");
for (i = 0; i < n; i++) {
printf("%i ", arr[i]);
}
printf("\n");
}

Error in function for Selection-Sort

My code for selection-sort
#include <stdio.h>
void selection_sort(int a[], int n);
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d",&size);
int b[size],i = 0;
printf("Enter %d integers to be sorted: ",size);
while(i++ < size)
scanf("%d",&b[i]);
selection_sort(b, size);
printf("Sorted integers(by selection sort) are: ");
for(int i = 0; i < size; i++)
printf("%d",b[i]);
return 0;
}
void selection_sort(int a[], int n)
{
while(n >= 0 )
{
if(n == 0)
break;
else
{
int i = 0, c = 0;
int largest = a[0];
while(i++ < n)
if(largest < a[i])
{
c = i ;
largest = a[i];
}
int temp = a[--n];
a[n] = largest;
a[c] = temp;
selection_sort(a, n);
}
}
}
on sorting the array in ascending order
3 4 1 2
is giving weird output
2293388 4 3 0
I checked this many time but failed to remove the problem.
What should I do to work it properly?
Algorithm used :
1. search for largest element in the array.
2. Move largest element to the last position of array.
3. Call itself recursively to sort the first n -1 element of the array.
Please don't give any other solution otherwise I will get confused.
EDIT
Ah, I see what goes wrong. First of all, while (i++ < n) does not do exactly what you expect it to do. It checks if the condition i < n is true, then it increments i. However, it seems that after the conditional check, i is already incremented in the body. So for example,
while (i++ < n)
printf ("%d ", i);
will print out (with n=4):
1 2 3 4
So you first need to change that. Secondly, the outer while-loop is not at all necessary. Using one loop will suffice. Again, change the while loop in here to while (i < n) and increment i in the body. SO the final code will be:
#include <stdio.h>
void selection_sort(int a[], int n);
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d", &size);
int b[size], i = 0;
printf("Enter %d integers to be sorted: ", size);
while(i < size) {
scanf("%d", &b[i]);
i++;
}
selection_sort(b, size);
printf("Sorted integers(by selection sort) are: ");
i = 0;
for(i = 0; i < size; i++)
printf("%d ", b[i]);
printf ("\n");
return 0;
}
void selection_sort(int a[], int n)
{
if(n == 0)
return;
else
{
int i = 0, c = 0;
int largest = a[0];
while(i < n) {
if(largest < a[i])
{
c = i;
largest = a[i];
}
i++;
}
int temp = a[--n];
a[n] = a[c];
a[c] = temp;
selection_sort(a, n);
}
}
I tested this with your given input (3 4 1 2) and it prints out a sorted list: 1 2 3 4.
Whenever you see such weird big numbers, its usually an array out of bounds issue. Please take a small data-set, say 5-6 numbers, and walk through your program. I am sure you can fix it. Good luck!!

Resources