Dynamic Program in C - c

Hi Guys i have edited the questions.Here is my entire code.I have given basic amount of readability to my program.I hope u guys can understand the program.
#include<stdio.h>
#include<stdlib.h>
int Max_Min(int,int,int,int *, int *);
int *Max,Number;
int main()
{
int n1, n2,Maximum_Element=0,*Max;
int i = 0, j = 0;
scanf("%d",&Number);
Max =(int *) malloc(sizeof(int)*Number);//Array Max is created
for (int k = 0;k <(Number/2);k++)
{
scanf("%d", &n1);
scanf("%d", &n2);
Max[k] = Max_Min(0,1,0,&n1,&n2);//Passing integer elements n1,n2 with flag 0
}
Maximum_Element=Max_Min(1,1,((sizeof(Max)*Number)/8),Max,Min);//Passing array elements Max,Min with flag 1 to function Max_Min
printf("Maximum_Element=%d", Maximum_Element);
return 0;
}
int Max_Min(int flag,int Max_Min_flag,int length,int *n1,int *n2)//n1 and n2 should be able to handle array and integers
{
int i=0,j = 0,k1,k2,Min1 = 0, Min2 = 0,count=0, Not_Zero = 0,x=0,y=0, *New_Max = 0,*New_Min;
/*Recursive Loop for splitting the array elements and calling the array */
if (flag == 1)
{
New_Max = (int *)(malloc(sizeof(int)*length));
for (;i <= ((length) / 2);i = i + 2)//
{
k1 = n1[i];
j = i + 1;
if (j <= ((length + 1) / 2))
{
k2 = n1[j];
New_Max[count] = Max_Min(0, 1, 0, &k1, &k2);//It is passing integer elements with flag 0 to function Max_Min
count++;
}
}
New_Max[count] = n1[j + 1];
for (int i = 0;i < count + 1;i++)
{
**/* Problem is assigning Max[i]=New_Max[i] is not getting assigned*/**
Max[i] = New_Max[i];//Copying from New_Max to Max because New_Max will be overwritten,so possible chaunce of dataloss
Not_Zero++;
}
while ((sizeof(Max) / 4 - (Not_Zero))>0)
{
Max[Not_Zero] = 0;
Not_Zero++;
}
/*Logic for calling recursive functions based on the count*/
if (count > 1)
{
count--;
Max_Min(1, 1, count, Max, Min);//Calling Recursive function by Passing Entire Arrays with flag 1.
}
else if (count == 1 && Max[1] == 0)
{
*n1 = Max[0];
*n2 = Min[0];
}
else if (count == 1 && Max[2] == 0)
{
Max_Min(1, 1, count + 1, Max, Min);
count--;
}
}
/*Logic for Finding Maximum & Minimum element is present down*/
if (flag == 0)
{
printf("flag");
if (Max_Min_flag == 1)
{
if (*n1 > *n2)
{
}
else if ((*n1 < *n2) && Max_Min_flag == 1)
{
int temp = 0;
temp = *n1;//5
*n1 = *n2;//7
*n2 = temp;//5
}
}
else if (Max_Min_flag == 2)
{
if (*n1 > *n2)//7>2
{
int temp = 0;
temp = *n1;//2
*n1 = *n2;//2
*n2 = temp;//2,7
}
else if (*n1 < *n2)
{
}
}
}
return *n1;//7
}
Problem is assigning Max[i]=New_Max[i] in function Max_Min().It shows Run time error as "Access violation writing location 0x00000000."

First you need to #include <stdlib.h> to use malloc
You must declare your function before using it.
func must return int*.
Also in func "n", first "Max", and second "Max" needs to be the same variable. Rename "n" to "Max"
This is the code corrected with an extra printf;
#include <stdio.h>
#include <stdlib.h>
int *Max,Number=5;
int* func(int *Max)
{
for(int j=0;j<5;j++)
Max[j]=j;//Its not working in this line
return Max;
}
int main()
{
Max=(int *) malloc(sizeof(int)*Number);
for(int i=0;i<5;i++)
Max[i]=i;
int* x = func(Max);
for(int i=0;i<5;i++)
printf("%d", x[i]);
}

The following contains only minor adaptations of your code and it runs fine:
int *func(int *n);
int *Max,Number=5;
int main()
{
int *x,i;
Max=(int *) malloc(sizeof(int)*Number);
for(i=0;i<Number;i++)
Max[i]=i;
x=func(Max);
free(Max);
return(0);
}
int *func(int *n)
{
int j;
for (j=0;j<Number;j++)
n[j]=Number-j; // reverse the number, just to check
return Max;
}

Related

C - initialized pointer throws exception about nullptr

I have a code that intends to find minimal value using pointers, using a function.
The problem is that even though I initialize the pointer while debugging it shows:
Exception thrown: read access violation.
min was nullptr.
At line 37. The code can be seen below:
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
int tab_min(const int* tab, int size, int *min);
int main()
{
int limit;
int tab[100];
int * ptab = tab;
int min = 2;
int *pmin = &min;
printf("Number of elements: ");
scanf("%d", &limit);
printf("List the elements \n");
for (int i = 0; i < limit; i++)
{
scanf("%d", &*(ptab + i));
}
tab_min(ptab, limit, pmin);
return 0;
}
int tab_min(const int* tab, int size, int *min)
{
if ((tab == NULL) || (size <= 0) || (min = NULL))
{
return 0;
}
else
{
for (int i = 0; i < size; i++)
{
if (*(tab + i) < *min) *min = *(tab + i); //Exception is here
}
return 0;
}
}
Can somebody please explain to me what is wrong with my reasoning?
The critical error is that if ((tab == NULL) || (size <= 0) || (min = NULL)) assign var min to NULL.
if you need to record the minimum value, you can use pointer address as parameter
int tab_min(const int* tab, int size, int **min);
and
if (*(tab + i) < **min) *min = (tab + i);
and call like
tab_min(ptab, limit, &pmin);
Thanks #Gerhardh for pointing out my mistake

C - How to implement priority queue using binary heap with tie-breaker?

I have to implement a priority queue using binary heap in C for the university assignment. Program should get the n values from input, when value is 0, it should print the ID number(so, if task that was added as 5th element has the highest priority 7, print "5") and remove the highest-priority task from queue, and when value>0 it should add new node. To implement ID's and priority, I used arrays of structs.
The task would be quite simple, if not the fact that it should also print lower ID's if the priority of elements are the same...
I've done my research, but the only advice that I've managed to found is to modify the fragments of typical heap functions (insertkey, heapify) to also look for elements' ID. I've tried to do this, but I have no idea what went wrong - elements are still not sorted in the way I want them to be. I would be grateful for any piece of advice and tips!
Code:
#include <stdio.h>
#define SIZE 99999
int heapsize = 0;
int count = 0;
struct pqueue
{
int priority;
int id;
};
struct pqueue A[SIZE];
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void initializearray()
{
for(int i=0; i<SIZE; i++)
{
A[i].priority = 0;
A[i].id = 0;
}
}
void printheap(); //prototype of debugging function
int left(int i)
{
return (i * 2) + 1;
}
int right(int i)
{
return (i * 2) + 2;
}
int parent(int i)
{
return ((i - 1) / 2);
}
void insertkey(int z)
{
heapsize++;
int i = heapsize - 1;
A[i].priority = z;
count++;
A[i].id = count;
while (i != 0 && A[parent(i)].priority < A[i].priority)
{
swap(&A[i].priority, &A[parent(i)].priority);
swap(&A[i].id, &A[parent(i)].id);
i = parent(i);
}
i = heapsize-1;
while(i != 0 && A[parent(i)].priority == A[i].priority && A[parent(i)].id > A[i].id )
{
swap(&A[i].priority, &A[parent(i)].priority);
swap(&A[i].id, &A[parent(i)].id);
i = parent(i);
}
// printheap();
}
void maxheapify(int i)
{
int l = left(i);
int r = right(i);
int largest;
if (l <= heapsize && A[l].priority >= A[i].priority)
{
largest = l;
if(A[l].priority == A[i].priority)
{
if(A[l].id < A[i].id)
{
largest = l;
}
else
{
largest = i;
}
}
}
else
{
largest = i;
}
if (r <= heapsize && A[r].priority >= A[largest].priority)
{
largest = r;
if(A[r].priority == A[largest].priority)
{
if(A[r].id < A[largest].id)
{
largest = r;
}
}
}
if (largest != i)
{
swap(&A[i].priority, &A[largest].priority);
swap(&A[i].id, &A[largest].id);
maxheapify(largest);
}
}
int extractmax()
{
int max = A[0].id;
A[0].priority = A[heapsize-1].priority;
A[0].id = A[heapsize-1].id;
heapsize--;
//printheap();
maxheapify(0);
return max;
}
void printheap() // debug function
{
for(int i = 0; i < heapsize; i++)
{
printf("prio %d id %d \n", A[i].priority, A[i].id);
}
}
int main()
{
int n;
int z;
initializearray();
scanf("%d", &n);
for(int i=0; i<n; i++)
{
scanf("%d", &z);
if(z != 0)
{
insertkey(z);
}
else
{
int local = extractmax();
if(local != 0 && heapsize+1 != 0)
{
printf("%d\n", local);
// printheap();
}
}
}
return 0;
}
Example input:
7
3 0 0 2 8 8 0
Output:
1
3
Example input (here comes the problem:)
10
1 1 1 1 2 0 0 0 0 0
Output:
5
3
2
4
1
Expected output:
5
1
2
3
4
Thank you for your time!
Instead of incorporating the logic directly into the heap implementation, write a comparison function that considers the id if the priorities are the same:
int pqless(const struct pqueue *a, const struct pqueue *b)
{
if (a->priority < b->priority) return 1;
if (a->priority > b->priority) return 0;
return (a->id > b->id);
}
This function returns true if a's priority is less than b's. If both priorities are equal, it returns true if a's id is smaller than b's.
Now update your heap code. Wherever you compare the priorities in the original code, now just call the function:
void insertkey(int z)
{
int i = heapsize++;
A[i].priority = z;
A[i].id = ++count;
while (i != 0 && pqless(&A[parent(i)], &A[i])) {
swap(&A[i].priority, &A[parent(i)].priority);
swap(&A[i].id, &A[parent(i)].id);
i = parent(i);
}
}
void maxheapify(int i)
{
int l = left(i);
int r = right(i);
int largest = i;
if (l <= heapsize && !pqless(&A[l], &A[i])) largest = l;
if (r <= heapsize && !pqless(&A[r], &A[largest]))largest = r;
if (largest != i) {
swap(&A[i].priority, &A[largest].priority);
swap(&A[i].id, &A[largest].id);
maxheapify(largest);
}
}

assigned value to dynamic array created in void function doesnt return the same value in main()

I have a problem with dynamic arrays in C. My program was working perfectly, but I was asked to put the creation of dynamic array into a seperate void. I did it, and it still worked great, but then I had to assign a value to a certain point of the created array in void, and make it return the said value, however, what I get is a random value. The function works by sending a pointer and the lenght of required array into void, and then makes the pointer into a dynamic array.
#include <stdio.h>
#include <stdlib.h>
#define MAX 255
void ieskom (int skaiciai[],int n, int *de, int *me, int *n1, int *n2)
{
int i = 0;
int j = 0;
int nr1 = 0;
int nr2 = 0;
int temp = 0;
int temp1 = 0;
int eile = 0;
int eile1 = 0;
int *did;
did = (int*)calloc(n,sizeof(int));
if (did==NULL)
{
printf("Nepriskirta atminties.");
exit(0);
}
int *maz;
maz = (int*)calloc(n,sizeof(int));
if (maz==NULL)
{
printf("Nepriskirta atminties.");
exit(0);
}
i = 0;
for (i = 0; i < n; i++)
{
if (skaiciai[i] < skaiciai[i+1])
{
did[j] = did[j] + 1;
if (did[j] > temp)
{
eile = j;
temp = did[j];
nr1 = i+1;
}
}
else
{
did[j] = did[j] + 1;
if (did[j] > temp)
{
eile = j;
temp = did[j];
nr1 = i+1;
}
j = j + 1;
}
}
j = 0;
for (i = 0; i < n; i++)
{
if (skaiciai[i] > skaiciai[i+1])
{
maz[j] = maz[j] + 1;
if (maz[j] > temp1)
{
eile1 = j;
temp1 = maz[j];
nr2 = i+1;
}
}
else
{
maz[j] = maz[j] + 1;
if (maz[j] > temp1)
{
eile1 = j;
temp1 = maz[j];
nr2 = i+1;
}
j = j + 1;
}
}
*de = did[eile];
*me = maz[eile1];
*n1 = nr1;
*n2 = nr2;
free(did);
free(maz);
}
/*int masyvas(x)
{
int y;
y = (int*)malloc(x*sizeof(int));
return y;
}*/
void *masyvas (int *skaiciai, int n)
{
*skaiciai = (int*)malloc(n*sizeof(int));
skaiciai[2] = 5;
return skaiciai;
}
int main()
{
int n1 = 0;
int n2 = 0;
int de = 0;
int me = 0;
int i = 0;
int n = 0;
int *skaiciai;
scanf("%d", &n);
// skaiciai = masyvas(n); // naudojant int
masyvas(&skaiciai, n);
printf("2 = %d", skaiciai[2]);
if (skaiciai==NULL)
{
printf("Nepriskirta atminties.");
exit(0);
}
for (;i < n; i++)
{
scanf("%d", &skaiciai[i]);
}
ieskom (skaiciai, n, &de, &me, &n1, &n2);
if (de > me)
{
printf("Elementu numeriai:");
printf(" %d", n1-de+1);
printf(" %d\n", n1);
printf("\nAtstumas tarp ju: %d", de-2);
}
else
{
printf("Elementu numeriai:");
printf(" %d", n2-me+1);
printf(" %d\n", n2);
printf("\nAtstumas tarp ju: %d", me-2);
}
free(skaiciai);
getchar();
getchar();
return 0;
}
The problem is in void masyvas and printf skaicia[2] - I assign a certain value to skaiciai[2], yet it prints a random one. How do I fix it?
EDIT: Thank you for your answers and explanations, it really helped me a lot! I know have solved my problem, and most importantly, I know why it was a problem in the first place.
First of all, you should translate variables and texts to english (your code lack of comments, this should apply to them too).
Next your masyvas() function returns a pointer to the allocated array (why void* ?!) but when you call it you don't get the returned value.
You have to choose: either you pass a pointer to your function (an array is a pointer, to if you want an array to be allocated from a function you have to pass a pointer to the pointer, so a int **), or you use the returned value.
Allocating with returned value:
// this function allocates a int* tab of size n and set one value
int *allocate_tab(int n) {
int *tmp;
tmp = malloc(n*sizeof(int));
if (tmp == NULL) {
return(NULL); // failed
}
tmp[2] = 5;
return(tmp);
}
// in main (or other function)
int *mytab;
mytab = alloc_tab(45);
Allocating by passing a pointer to the array:
void alloc_tab(int **tab, int n) {
*tab = malloc(n*sizeof(int));
if (*tab == NULL) {
return;
}
(*tab)[2] = 5;
}
// in main (or other)
int *mytab;
alloc_tab(&mytab, 45);
If you can't understand this stuff I guess you should read more about memory, allocation and pointers.
You need to pass a pointer-to-pointer here and do not need to return anything.
void masyvas (int **skaiciai, int n)
{
*skaiciai = (int*)malloc(n*sizeof(int));
(*skaiciai)[2] = 5;
}
When you declare int *skaiciai, the variable is a pointer to type int. skaiciai holds the address that points to an int. When you pass &skaiciai, you're passing the address of the address that points to an int. So because this is an address of an address, its a double pointer.

Shorter way to get 5 highest and 5 lowest values without changing the stack

So here is my code . I am trying to find a short way to make this programme work withouth changing any of the arregment.I have been tought the buble way i think its called to arrange a group from highest to lowest but it clearly say in my given orders not to change the entire group.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int randomInRange (unsigned int min, unsigned int max)
{
//srand(time(NULL));
int base_random = rand();
if (RAND_MAX == base_random) return randomInRange(min, max);
int range = max + 1 - min,
remainder = RAND_MAX % range,
bucket = RAND_MAX / range;
if (base_random < RAND_MAX - remainder) {
return min + base_random/bucket;
} else {
return randomInRange (min, max);
}
}
int main()
{
int ari,i,min,max;
printf("Gi'me length of the group")
scanf("%d",&ari);
int pinakas[ari];
printf("Gi'me lowest and highest values");
scanf("%d",&min);
scanf("%d",&max);
for(i = 0; i < ari; i++)
{
pinakas[ari] = randomInRange(min,max);
}
int el,meg,c;
el = max+1;
meg = min-1;
c = 0;
printf("Highest Lowest");
while( c != 4;)
{
for(i = 0; i < ari; i++)
{
if(el > pinakas[ari])
{
el = pinakas[ari];
}
if( meg < pinakas[ari])
{
meg = pinakas[ari];
}
if(i == 4)
{
printf("%d %d",el,meg);
( is there something that i can put here is order to make el,meg to go for the second lowest ,second highest? and so on till i get the 5 highest and 5 lowests.Keep in mind the the lowest length of my group will be pinakas[5].)
}
}
c++;
}
For each item in the array, up to 5 comparisons are done for the min list and 5 for the max list.
Suggest calling a function to do this in a tidy fashion.
#include<assert.h>
// `list` is `const` as OP says "withouth changing any of the arregment".
void sort_ends(const int *list, size_t listlen, int *minlist, int *maxlist,
size_t mlen) {
assert(list);
assert(minlist);
assert(maxlist);
assert(mlen >= 1);
assert(listlen >= mlen);
minlist[0] = list[0];
// For each element after the first ...
for (size_t i = 1; i < listlen; i++) {
int mincandidate = list[i];
size_t mini = i;
if (mini > mlen) mini = mlen;
do {
mini--;
if (mincandidate >= minlist[mini])
break;
// swap mincandidate and minlist[mini]
int t = mincandidate;
mincandidate = minlist[mini];
minlist[mini] = t;
} while (mini > 0);
}
// Do similar for maxlist, left for OP
}
int main() {
int ari;
// ...
int pinakas[ari];
// ...
int mlen = 5;
int minlist[mlen];
int maxlist[mlen];
sort_ends(pinakas, ari, minlist, maxlist, mlen);
return 0;
}
Alternative approach, find min index and then memove().

Trouble creating a descending heap sort in C

void heapSort(int list[], int last)
{
// Local Declarations
int sorted;
int holdData;
int walker;
// Statements
for (walker = 1; walker <= last; walker++)
reheapUp (list, walker);
// Min Heap created. Now to sort!
sorted = last;
while (sorted > 0)
{
holdData = list[0];
list[0] = list[sorted];
list[sorted] = holdData;
sorted--;
reheapDown (list, 0, sorted, moves, comparisons);
}
return;
}
void reheapUp (int heap[], int newNode)
{
// Local Declarations
int parent;
int hold;
// Create a min heap
// Statements
if (newNode)
{
parent = (newNode - 1) / 2;
if (heap[newNode] > heap[parent]) // Only change made from ascending order
{
hold = heap[parent];
heap[parent] = heap[newNode];
heap[newNode] = hold;
reheapUp (heap, parent);
}
}
return;
}
void reheapDown (int heap[], int root, int last)
{
// Local Declarations
int hold;
int leftKey;
int rightKey;
int largeChildKey;
int largeChildIndex;
// Statements
if ((root * 2 + 1) <= last)
{
// There is atleast one child
leftKey = heap[root * 2 + 1];
if ((root * 2 + 2) <= last) {
rightKey = heap[root * 2 + 2];
}
else
rightKey = -1;
// Determine which child is larger
if (leftKey > rightKey)
{
largeChildKey = leftKey;
largeChildIndex = root * 2 + 1;
}
else
{
largeChildKey = rightKey;
largeChildIndex = root * 2 + 2;
}
// Test if root > large subtree
if (heap[root] < heap[largeChildIndex])
{
// parent < child
hold = heap[root];
heap[root] = heap[largeChildIndex];
heap[largeChildIndex] = hold;
reheapDown(heap, largeChildIndex, last);
}
}
return;
}
I got ascending order to heap sort to function by creating a max heap. I read that to create a descending order heap sort I need to create a min heap which I did as shown by changing heap[newNode] < heap[parent] to heap[newNode] > heap[parent] as shown in the code. However, it is still out order. Therefore, I wanted to do what are the other steps? Do I need to alter reheapDown somehow as well?
You need to change all value comparisons you make like heap[root] < heap[largeChildIndex] you didn't mention you changed.
First of all you need to change every comparison operators accordingly, just take them all and think of the problem.
Secondly you only have to reheapUp to (last/2) to create the heap, because the key at (last/2+1) doesn't have any childs.
And I made some heap-sort in C before and I had way less lines of code, and only had one "heapify" function. You might want to look at your code and try to simplify things.
EDIT : if you want some inspiration here is what I did
void fixHeap(int position,int length)
{
int child = (2*position)+1;
int temp;
while (child<=length)
{
if (child<length && vector[child]<vector[child+1])
{
child++;
}
if (vector[position]<vector[child])
{
temp = vector[position];
vector[position] = vector[child];
vector[child] = temp;
position = child;
child = (2*position)+1;
}
else
{
return;
}
}
}
void heapSort(int vector[],int N)
{
int counter;
int temp;
for (counter=(N-1)/2; counter>=0; counter--)
{
fixHeap(counter,N-1);
}
for (counter=N-1; counter>0; counter--)
{
temp = vector[counter];
vector[counter] = vector[0];
vector[0] = temp;
fixHeap(0,counter-1);
}
}
Here is heap sort using min heap implementation. Have a look, if it helps!
#include "stdafx.h"
#define LEFT(i) (2 * (i))
#define RIGHT(i) (((2 * (i)) + 1))
#define PARENT(i) ((i) / 2))
void print_heap(int input[], int n)
{
int i;
printf("Printing heap: \n");
for (i = 0; i < n; i++)
printf("%d ", input[i]);
printf("\n");
}
void swap_nodes(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void min_heapify(int input[], int i, int n)
{
int least;
int l = LEFT(i + 1) - 1; // Get 0 based array index
int r = RIGHT(i + 1) - 1; // Get 0 based array index
if (l < n && input[l] < input[i]) {
least = l;
} else {
least = i;
}
if (r < n && input[r] < input[least]) {
least = r;
}
if (least != i) {
swap_nodes(&input[i], &input[least]);
min_heapify(input, least, n);
}
}
void heapify(int input[], int n)
{
for (int i = n/2; i >= 0; i--)
min_heapify(input, i, n);
}
void heap_sort(int input[], int n)
{
heapify(input, n);
for (int i = n - 1; i >= 1; i--) {
swap_nodes(&input[0], &input[i]);
n = n - 1;
min_heapify(input, 0, n);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int input[] = {5, 3, 17, 10, 84, 19, 6, 22, 9, 1};
int n = sizeof(input) / sizeof(input[0]);
print_heap(input, n);
heap_sort(input, n);
print_heap(input, n);
return 0;
}

Resources