Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 31

MINISTRY OF EDUCATION, CULTURE AND RESEARCH

OF THE REPUBLIC OF MOLDOVA


Technical University of Moldova
Faculty of Computers, Informatics and Microelectronics
Department of Software and Automation Engineering

Postoronca Dumitru

Report
Laboratory Work No.2

of the "Data Structures and Algorithms" course

Checked:
Burlacu Natalia, PhD, associate professor
Department of Software and Automation Engineering,
FCIM Faculty, UTM

Chisinau – 2023
Task:

1. Solve the following problems in C, writing your own functions according


to the given statements. Write the solution of the problem by procedural approach
in two versions:

A. with the use of the method of transmitting the parametric functions by


value;

B. with the use of the method of passing parameters of functions by


address/pointers (the formal parameter will be a pointer to the value of the
corresponding object).

C. To draw the block diagram corresponding to the solved problem.

2. Modify the content of your problems emerging from the possibilities that are
missing, but which can be brought as added value in the condition of the existing
problem. Formulate and present in writing the modified condition; to solve in C
your problem in the modified version, using functions developed by you
3. Executable code, with relevant comments and flow charts

Version 1 with parameters passed as values(Quick sort and Shell sort)

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<math.h>
/////////////////////////Prerequisites////////////////////////////////
//function to swap 2 values by their adresses
void swap(int *x, int *y){
int temp=*x;
*x=*y;
*y=temp;
}
//functions to set and reset diplaying color in output
void green(){
printf("\033[0;32m");
}
void red(){
printf("\033[0;31m");
}
void reset(){
printf(" \033[0;37m");
}
//get dinamically the array
int array_input(int** arr){
int size = 0; // Current size of the array
int capacity = 0; // Capacity of the array (allocated memory)
int input;

printf("Enter integers (enter a letter to finish):\n");


while (1) {
int result = scanf("%d", &input);
if (result == 0) break;//check if input is not an integer

//check if the array needs to be resized


if (size == capacity) {
capacity = (capacity == 0) ? 1 : capacity + 10;//add capacity

int *temp = (int*)realloc(*arr, capacity *


sizeof(int));//memory realoc

if (temp == NULL) {
printf("Memory reallocation failed.\n");
free(*arr);
return 1;
}
*arr = temp;
}
(*arr)[size] = input;
size++;
}

return size;
}

//function to print the sorted array and used algorithm


void print_sort_result(char *sort_type, int* arr, int n){
int size = strlen(sort_type);

green();
for (int i = 0; i < size; i++)//prints used algorithm
printf("%c", sort_type[i]);
reset();
for (int i = 0; i < n; i++)//prints sorted array
printf("%i ", arr[i]);
printf("\n");

//print array
void print_array(int arr[], int n){
for(int i=0;i<n;i++)
printf("%i ", arr[i]);
printf("\n");
}
/////////////////////////////////////////////////////////////////////////
void copy_arr(int or_arr[], int mod_arr[], int n){
for(int i=0; i<n; i++){
mod_arr[i]=or_arr[i];
}
}
void print_task_1(int orig[], int mod[], int n, int k){
red();
printf("Original array:\t");
reset();
for(int i=0; i < n; i++){
printf("%i ", orig[i]);
}

for(int i=0; i < n; i++){


if(mod[(i+n-1)%n]<mod[i] && mod[(i+n+1)%n]<mod[i]){
mod[i]=pow(mod[i], k);
}
}printf("\n");
red();
printf("Modified array:\t");
reset();
for(int i=0; i < n; i++){
printf("%i ", mod[i]);
}printf("\n");
}
//task III
int partition(int *arr, int low, int hight, int ascending){
int piv_val = arr[hight];
int i = low;
for (int j = low; j < hight; j++){
if(ascending){
if(piv_val>=arr[j]){
swap(&arr[i], &arr[j]);
i++;
}
}
else{
if(piv_val<=arr[j]){
swap(&arr[i], &arr[j]);
i++;
}
}

}
swap(&arr[i], &arr[hight]);
return i;
}
int quicksort_recursion(int *arr,int low, int hight, int ascending){
if (low<hight)
{
int piv_index = partition(arr, low, hight, ascending);
quicksort_recursion(arr, low, piv_index-1, ascending);
quicksort_recursion(arr, piv_index+1, hight, ascending);
}

}
int quicksort(int or_arr[], int n, int ascending){
int arr[n];
for (int i = 0; i < n; i++)arr[i]=or_arr[i];
quicksort_recursion(arr, 0, n-1, ascending);
if (ascending)
print_sort_result("Quick sort ascending", arr, n);
else
print_sort_result("Quick sort descending", arr, n);
return 0;
}
//task IV
void shellsort(int or_arr[], int n, int ascending){
int arr[n];
for (int i = 0; i < n; i++)arr[i]=or_arr[i];
//determine gap and reduce it with each iteration
for(int gap=n/2; gap>0; gap/=2){
//take each element staring from the gap size and go 1 by one
for (int i = gap; i < n; i++){
//save current value in a temp variable
int temp = arr[i];
int j;
//compare and change values of elements till they are in
correct position
if(ascending){
for(j=i; j>=gap && arr[j-gap]>temp;j-=gap){
arr[j]=arr[j-gap];
}
}else{
for(j=i; j>=gap && arr[j-gap]<temp;j-=gap){
arr[j]=arr[j-gap];
}
}

arr[j]=temp;
}

}
(ascending)?print_sort_result("Shell sort ascending: ", arr,
n):print_sort_result("Shell sort descending: ", arr, n);
}
int main(){
int *or_arr=NULL, k;
int *mod_arr=NULL;
int n=array_input(&or_arr);
mod_arr=(int*)malloc(sizeof(int)*n);

copy_arr(or_arr, mod_arr, n);


scanf("%c", &k);//scan k
printf("Type k: ");scanf("%i", &k);

//task I and II
print_task_1(or_arr, mod_arr, n, k);

//task III
quicksort(or_arr, n, 1);//1 - ascending
quicksort(or_arr, n, 0);//0 - descending

//task IV
shellsort(mod_arr, n, 1);
shellsort(mod_arr, n, 0);
free(or_arr);
free(mod_arr);
return 0;
}
Version 2 with parameters passed as pointers (Merge and Counting)

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<math.h>
/////////////////////////Prerequisites////////////////////////////////
//function to swap 2 values by their adresses
void swap(int *x, int *y){
int temp=*x;
*x=*y;
*y=temp;
}
//functions to set and reset diplaying color in output
void green(){
printf("\033[0;32m");
}
void red(){
printf("\033[0;31m");
}
void reset(){
printf(" \033[0;37m");
}
//get dinamically the array
int array_input(int** arr){
int size = 0; // Current size of the array
int capacity = 0; // Capacity of the array (allocated memory)
int input;

printf("Enter integers (enter a letter to finish):\n");


while (1) {
int result = scanf("%d", &input);
if (result == 0) break;//check if input is not an integer

//check if the array needs to be resized


if (size == capacity) {
capacity = (capacity == 0) ? 1 : capacity + 10;//add capacity

int *temp = (int*)realloc(*arr, capacity *


sizeof(int));//memory realoc

if (temp == NULL) {
printf("Memory reallocation failed.\n");
free(*arr);
return 1;
}
*arr = temp;
}

(*arr)[size] = input;
size++;
}

return size;
}

//function to print the sorted array and used algorithm


void print_sort_result(char *sort_type, int* arr, int n){
int size = strlen(sort_type);

green();
for (int i = 0; i < size; i++)//prints used algorithm
printf("%c", sort_type[i]);
reset();
for (int i = 0; i < n; i++)//prints sorted array
printf("%i ", arr[i]);
printf("\n");

//print array
void print_array(int arr[], int n){
for(int i=0;i<n;i++)
printf("%i ", arr[i]);
printf("\n");
}
/////////////////////////////////////////////////////////////////////////
void copy_arr(int **or_arr, int **mod_arr, int *n){
for(int i=0; i<*n; i++){
(*mod_arr)[i]=(*or_arr)[i];
}
}
void print_task_1(int **orig, int **mod, int *n, int *k){
red();
printf("Original array:\t");
reset();
for(int i=0; i < *n; i++){
printf("%i ", (*orig)[i]);
}

for(int i=0; i < *n; i++){


if((*mod)[(i+(*n)-1)%(*n)]<(*mod)[i] && (*mod)[(i+(*n)+1)%
(*n)]<(*mod)[i]){
(*mod)[i]=pow((*mod)[i], *k);
}
}printf("\n");

red();
printf("Modified array:\t");
reset();
for(int i=0; i < *n; i++){
printf("%i ", (*mod)[i]);
}printf("\n");
}

//task III
int determine_min(int **arr, int *n){
int min=0;

for (int i = 0; i < *n; i++)


if(min>(*arr)[i])min=(*arr)[i];

for (int i = 0; i < *n; i++)


//substract the minimum element to get array of nonegative numbers
(*arr)[i]-=min;
return min;
}
void process_count_arr(int **arr, int **count, int *n, int *maxN, int
*count_size) {
for (int i = 0; i < *n; i++) {
if ((*arr)[i] > *maxN) *maxN = (*arr)[i];
}
*count_size = *maxN + 1;
*count = (int*)malloc(sizeof(int) * (*count_size));
if (*count == NULL) {
printf("Memory allocation failed for the count array.\n");
return;
}
//initialize count array with zeros
for (int i = 0; i < (*count_size); i++) {
(*count)[i] = 0;
}
//populate count array
for (int i = 0; i < *n; i++)
(*count)[(*arr)[i]]++;
//modify the count array
for (int i = 1; i < (*count_size); i++)
(*count)[i] += (*count)[i-1];

void countingsort(int **or_arr, int *n, int ascending){


int *arr; // stores input array
int *count = NULL; // stores count array
int *result; // stores resulting array
int maxN = 0, count_size, right_index;
int int_normal;
arr=(int*)malloc(*n * sizeof(int));
copy_arr(&(*or_arr), &arr, n);
process_count_arr(&arr, &count, n, &maxN, &count_size);

int_normal=determine_min(&arr, n);//stores the minimum of array


result = (int*)malloc(sizeof(int) * (*n));

if (ascending){
for (int i = (*n)-1; i >= 0; i--) {
right_index = count[arr[i]] - 1;
result[right_index] = arr[i];
count[arr[i]]--;
}
}else{
for (int i = 0; i < *n; i++) {
right_index = (*n)-count[arr[i]];
result[right_index] = arr[i];
count[arr[i]]--;
}
}

for(int i = 0; i < (*n); i++)


result[i]+=int_normal;//normalize array back to original values
if (ascending){
print_sort_result("Counting sort ascending: ", result, *n);
}else{
print_sort_result("Counting sort descending: ", result, *n);
}

free(count);
free(result);
}
//task IV
void merge(int* arr, int l, int m, int r, int ascending){
int n1 = m-l+1;
int n2 = r-m;
int left_arr[n1], right_arr[n2];
for (int i = 0; i < n1; i++) left_arr[i]=arr[l+i];//copy left half in
left_arr
for (int i = 0; i < n2; i++) right_arr[i]=arr[m+1+i];//copy right half
in right_arr
int i=0, j=0, k=l;
while(i<n1 && j<n2){
if (ascending){
if (left_arr[i]>=right_arr[j]){
arr[k]=right_arr[j];
j++;
} else{
arr[k]=left_arr[i];
i++;
}
k++;
}else{
if (left_arr[i]<=right_arr[j]){
arr[k]=right_arr[j];
j++;
} else{
arr[k]=left_arr[i];
i++;
}
k++;
}
}
while (i < n1) {//introduce the remaining part in array
arr[k] = left_arr[i];
i++;
k++;
}
while (j < n2) {//introduce the remaining part in array
arr[k] = right_arr[j];
j++;
k++;
}
}
int merge_sort_recursion(int** arr, int l, int r, int ascending){//l-left,
r-right
if (l < r){
int m =l + (r - l) / 2;
merge_sort_recursion(&(*arr), l, m, ascending);
merge_sort_recursion(&(*arr), m + 1, r, ascending);
merge(*arr, l, m, r, ascending);
}

}
int merge_sort(int** or_arr, int *n, int ascending){
int *arr;
arr=(int*)malloc(sizeof(int)*(*n));
copy_arr(&(*or_arr), &arr, n);
int l = 0;
int r = *n - 1;
merge_sort_recursion(&arr, l, r, ascending);
(ascending)?print_sort_result("Merge_sort ascending: ", arr,
*n):print_sort_result("Merge_sort descending: ", arr, *n);
free(arr);
}

int main(){
int *or_arr=NULL, k;
int *mod_arr=NULL;
int n=array_input(&or_arr);
mod_arr=(int*)malloc(sizeof(int)*n);

copy_arr(&or_arr, &mod_arr, &n);


scanf("%c", &k);//scan k
printf("Type k: ");scanf("%i", &k);

//task I and II
print_task_1(&or_arr, &mod_arr, &n, &k);

//task III
countingsort(&or_arr, &n, 1);//1 - ascending
countingsort(&or_arr, &n, 0);//0 - descending

//task IV
merge_sort(&mod_arr, &n, 1);
merge_sort(&mod_arr, &n, 0);
free(or_arr);
free(mod_arr);
return 0;
}
Version with modified code

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<math.h>
/////////////////////////Prerequisites////////////////////////////////
//function to swap 2 values by their adresses
void swap(int *x, int *y){
int temp=*x;
*x=*y;
*y=temp;
}
//functions to set and reset diplaying color in output
void green(){
printf("\033[0;32m");
}
void red(){
printf("\033[0;31m");
}
void reset(){
printf(" \033[0;37m");
}
//get dinamically the array
int array_input(int** arr){
int size = 0; // Current size of the array
int capacity = 0; // Capacity of the array (allocated memory)
int input;

printf("Enter integers (enter a letter to finish):\n");


while (1) {
int result = scanf("%d", &input);
if (result == 0) break;//check if input is not an integer

//check if the array needs to be resized


if (size == capacity) {
capacity = (capacity == 0) ? 1 : capacity + 10;//add capacity
int *temp = (int*)realloc(*arr, capacity *
sizeof(int));//memory realoc

if (temp == NULL) {
printf("Memory reallocation failed.\n");
free(*arr);
return 1;
}
*arr = temp;
}

(*arr)[size] = input;
size++;
}

return size;
}

//function to print the sorted array and used algorithm


void print_sort_result(char *sort_type, int* arr, int n){
int size = strlen(sort_type);

green();
for (int i = 0; i < size; i++)//prints used algorithm
printf("%c", sort_type[i]);
reset();
for (int i = 0; i < n; i++)//prints sorted array
printf("%i ", arr[i]);
printf("\n");

//print array
void print_array(int arr[], int n){
for(int i=0;i<n;i++)
printf("%i ", arr[i]);
printf("\n");
}
/////////////////////////////////////////////////////////////////////////
void copy_arr(int **or_arr, int **mod_arr, int *n){
for(int i=0; i<*n; i++){
(*mod_arr)[i]=(*or_arr)[i];
}
}
void print_task_1(int **orig, int **mod, int *n, int *k){
red();
printf("Original array:\t");
reset();
for(int i=0; i < *n; i++){
printf("%i ", (*orig)[i]);
}

for(int i=0; i < *n; i++){


if((*mod)[(i+(*n)-1)%(*n)]<(*mod)[i] && (*mod)[(i+(*n)+1)%
(*n)]<(*mod)[i]){
(*mod)[i]=pow((*mod)[i], *k);
}
}printf("\n");

red();
printf("Modified array:\t");
reset();
for(int i=0; i < *n; i++){
printf("%i ", (*mod)[i]);
}printf("\n");
}

//task III
int determine_min(int **arr, int *n){
int min=0;

for (int i = 0; i < *n; i++)


if(min>(*arr)[i])min=(*arr)[i];

for (int i = 0; i < *n; i++)


(*arr)[i]-=min;

return min;
}
void process_count_arr(int **arr, int **count, int *n, int *maxN, int
*count_size) {
for (int i = 0; i < *n; i++) {
if ((*arr)[i] > *maxN) *maxN = (*arr)[i];
}
*count_size = *maxN + 1;
*count = (int*)malloc(sizeof(int) * (*count_size));
if (*count == NULL) {
printf("Memory allocation failed for the count array.\n");
return;
}
//initialize count array with zeros
for (int i = 0; i < (*count_size); i++) {
(*count)[i] = 0;
}
//populate count array
for (int i = 0; i < *n; i++)
(*count)[(*arr)[i]]++;
//modify the count array
for (int i = 1; i < (*count_size); i++)
(*count)[i] += (*count)[i-1];
}

void countingsort(int **or_arr, int *n, int ascending){


int *arr; // stores input array
int *count = NULL; // stores count array
int *result; // stores resulting array
int maxN = 0, count_size, right_index;
int int_normal;
arr=(int*)malloc(*n * sizeof(int));
copy_arr(&(*or_arr), &arr, n);
process_count_arr(&arr, &count, n, &maxN, &count_size);

int_normal=determine_min(&arr, n);
result = (int*)malloc(sizeof(int) * (*n));

if (ascending){
for (int i = (*n)-1; i >= 0; i--) {
right_index = count[arr[i]] - 1;
result[right_index] = arr[i];
count[arr[i]]--;
}
}else{
for (int i = 0; i < *n; i++) {
right_index = (*n)-count[arr[i]];
result[right_index] = arr[i];
count[arr[i]]--;
}
}

for(int i = 0; i < (*n); i++)


result[i]+=int_normal;
if (ascending){
print_sort_result("Counting sort ascending: ", result, *n);
}else{
print_sort_result("Counting sort descending: ", result, *n);
}

free(count);
free(result);
}
//task IV
void merge(int* arr, int l, int m, int r, int ascending){
int n1 = m-l+1;
int n2 = r-m;
int left_arr[n1], right_arr[n2];
for (int i = 0; i < n1; i++) left_arr[i]=arr[l+i];//copy left half in
left_arr
for (int i = 0; i < n2; i++) right_arr[i]=arr[m+1+i];//copy right half
in right_arr
int i=0, j=0, k=l;
while(i<n1 && j<n2){
if (ascending){
if (left_arr[i]>=right_arr[j]){
arr[k]=right_arr[j];
j++;
} else{
arr[k]=left_arr[i];
i++;
}
k++;
}else{
if (left_arr[i]<=right_arr[j]){
arr[k]=right_arr[j];
j++;
} else{
arr[k]=left_arr[i];
i++;
}
k++;
}
}
while (i < n1) {//introduce the remaining part in array
arr[k] = left_arr[i];
i++;
k++;
}
while (j < n2) {//introduce the remaining part in array
arr[k] = right_arr[j];
j++;
k++;
}
}
int merge_sort_recursion(int** arr, int l, int r, int ascending){//l-left,
r-right
if (l < r){
int m =l + (r - l) / 2;
merge_sort_recursion(&(*arr), l, m, ascending);
merge_sort_recursion(&(*arr), m + 1, r, ascending);
merge(*arr, l, m, r, ascending);
}

}
int merge_sort(int** or_arr, int *n, int ascending){
int *arr;
arr=(int*)malloc(sizeof(int)*(*n));
copy_arr(&(*or_arr), &arr, n);
int l = 0;
int r = *n - 1;
merge_sort_recursion(&arr, l, r, ascending);
(ascending)?print_sort_result("Merge_sort ascending: ", arr,
*n):print_sort_result("Merge_sort descending: ", arr, *n);
free(arr);
}
//additional task
int isPythagoreanTriple(int a, int b, int c){
return (a*a + b*b == c*c);
}
void find_pitagorean_triples(int* arr, int* n){
for (int i = 0; i < *n; i++)
for (int j = i + 1; j < *n; j++)
for (int k = j + 1; k < *n; k++)
if (isPythagoreanTriple(arr[i], arr[j], arr[k])) {
printf("Pythagorean Triple: %d (i - %d), %d (i - %d),
%d (i - %d)\n", arr[i], i, arr[j], j, arr[k], k);
}
}
//function to compute the greatest common divisor (GCD) of two numbers
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}

//function to compute the GCD of all elements in the array


void gcdOfArray(int arr[], int size) {
int result = arr[0];
for (int i = 1; i < size; i++) {
result = gcd(result, arr[i]);
}
printf("Greatest common divizor of the array is: %d\n", result);
}

int main(){
int *or_arr=NULL, k;
int *mod_arr=NULL;
int n=array_input(&or_arr);
mod_arr=(int*)malloc(sizeof(int)*n);

copy_arr(&or_arr, &mod_arr, &n);


scanf("%c", &k);//scan k
printf("Type k: ");scanf("%i", &k);

//task I and II
print_task_1(&or_arr, &mod_arr, &n, &k);

//task III
countingsort(&or_arr, &n, 1);//1 - ascending
countingsort(&or_arr, &n, 0);//0 - descending

//task IV
merge_sort(&mod_arr, &n, 1);
merge_sort(&mod_arr, &n, 0);

//additional tasks
red();printf("Pitagorean triples in array:\n");reset();
find_pitagorean_triples(or_arr, &n);
gcdOfArray(or_arr, n);

free(or_arr);
free(mod_arr);
return 0;
}
In this version I added function to determine all Pythagorean numbers in the
array and a function to determine the GCD(greatest common divisor) or the
elements in array, also counting sort take in consideration counting with
negative numbers.

Flowchart of shared functions in all versions:

Figure 1.2 print sorted array


Figure 1.1 reading the array function
Figure 1.3 print original and modified array

Flow chart for functions in version 1:


Figure 1.4 main quicksort function

Figure 1.5 quicksort_recursion()


Figure 1.6 partition function

Figure 1.7 shellsort()


Flowcharts for version 2:

Figure 1.8 determine_min()


Figure 1.9 process_count_arr()
Figure 1.10 counting_sort()
Figure 1.11 merge()
Figure 1.12 mergesort_recursion()

Figure 1.13 mergesort()

Flowcharts for functions of modified version:


Figure 1.14 Pythagorean triple
Figure 1.15 GCD of 2 numbers

Figure 1.16 GCD of array


Output examples:

Version 1:

Version 2:

Modified version:
Conclusion

After this laboratory work, I have learned about new sorting algorithms like shell
sort and counting sort and implemented my knowledge in code. Also, I have
modified my code in order to make the counting sort more universal and be able to
count the arrays that contain negative elements. Also, I have introduced some
processing algorithms like finding the Pythagorean numbers in array and
determining the GCD (greatest common divisor) in array.
Bibliography

Figure 1.1 reading the input array - PlantUML Web Server

Figure 1.2 print sorted array - PlantUML Web Server

Figure 1.3 print original and modified array - PlantUML Web Server

Figure 1.4 call of main quick sort function - PlantUML Web Server

Figure 1.5 recursive quicksort function - PlantUML Web Server

Figure 1.6 partition function - PlantUML Web Server

Figure 1.7 shell sort - PlantUML Web Server

Figure 1.8 determine_min - PlantUML Web Server

Figure 1.9 process_count_arr - PlantUML Web Server

Figure 1.10 counting_sort - PlantUML Web Server

Figure 1.11 merge - PlantUMLWeb Server


Figure 1.12 merge_sort_recursion - PlantUML Web Server

Figure 1.13 mergesort - PlantUML Web Server

Figure 1.14 Pythagorean triple - PlantUML Web Server

Figure 1.15 GCD of 2 numbers - PlantUML Web Server

Figure 1.16 GCD of entire array - PlantUML Web Server

You might also like