Preorder Postorder Tree Traversal when RSON and LSON are given - c

If you input this
1111010000000 //LSON
GERLWIDAKONTH //DATA
1101101000110 //RSON
it should output the Preorder and Postorder of the given tree.
THE PROBLEM IS: MY PROGRAM DOESN'T PRINT THE CORRECT POSTORDER AND I CAN'T FIGURE OUT WHY. I hope you could help me. The Preorder is already correct but it is okay with me if you want to add anything to improve my codes. THANK YOU!:D
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 5
#define CASE 3
#define N 100
struct node{
char data;
struct node* llink;
struct node* rlink;
int tag;
};
typedef struct node Node;
typedef Node* NodePtr;
void twoPreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o);
void threePreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o);
void twoPostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o);
void threePostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o);
void printSequence(char *array[3], int size){
int i;
printf("LTAG: ");
for(i = 0; i < size; i++)
printf("%c", array[0][i]);
printf("\nDATA: ");
for(i = 0; i < size; i++)
printf("%c", array[1][i]);
printf("\nRTAG: ");
for(i = 0; i < size; i++)
printf("%c", array[2][i]);
printf("\n\n");
}
void onePreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
printf("%c", (*b)->data);
*counter = *counter+1;
int count = *counter;
int n = *size;
//printf("counter=%d\tsize=%d\n", count, n);
if(count == n){
return;
}
*o = (*b)->llink;
if(*o != NULL){
(*b)->llink = *a;
*a = *b;
*b = *o;
onePreorder(counter, size, a, b, o);
}
//printf("o NULL\n");
else{
twoPreorder(counter, size, a, b, o);
}
}
void twoPreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
*o = (*b)->rlink;
if(*o != NULL){
(*b)->rlink = *a;
(*b)->tag = 1;
*a = *b;
*b = *o;
onePreorder(counter, size, a, b, o);
}
//printf("o NULL\n");
threePreorder(counter, size, a, b, o);
}
void threePreorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
//printf("a = %c\n", (*a)->data);
if((*a) == NULL)
return;
else{
if((*a)->tag == 0){
*o = (*a)->llink;
(*a)->llink = *b;
*b = *a;
*a = *o;
twoPreorder(counter, size, a, b, o);
}
else{
*o = (*a)->rlink;
(*a)->rlink = *b;
(*a)->tag = 0;
*b = *a;
*a = *o;
threePreorder(counter, size, a, b, o);
}
}
}
void preorder1(int size, NodePtr root){
printf("Preorder:\t");
if(root == NULL)
return;
NodePtr a = NULL;
NodePtr b = malloc(sizeof(Node));
b = root;
NodePtr o = NULL;
int i = 0;
onePreorder(&i, &size, &a, &b, &o);
printf("\n");
}
void onePostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
*o = (*b)->llink;
if(*o != NULL){
(*b)->llink = *a;
*a = *b;
*b = *o;
onePostorder(counter, size, a, b, o);
}
else{
twoPostorder(counter, size, a, b, o);
}
}
void twoPostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
*o = (*b)->rlink;
if(*o != NULL){
printf("%c", (*b)->data);
(*b)->rlink = *a;
(*b)->tag = 1;
*a = *b;
*b = *o;
onePostorder(counter, size, a, b, o);
}
else{
printf("%c", (*b)->data);
threePostorder(counter, size, a, b, o);
}
}
void threePostorder(int *counter, int *size, NodePtr *a, NodePtr *b, NodePtr *o){
//printf("a = %c\n", (*a)->data);
if((*a) == NULL)
return;
else{
if((*a)->tag == 0){
*o = (*a)->llink;
(*a)->llink = *b;
*b = *a;
printf("%c", (*b)->data);
*counter++;
int i = *counter;
int n = *size;
if(i == n)
return;
*a = *o;
twoPostorder(counter, size, a, b, o);
}
else{
*o = (*a)->rlink;
(*a)->rlink = *b;
(*a)->tag = 0;
*b = *a;
printf("%c", (*b)->data);
*counter++;
int i = *counter;
int n = *size;
if(i == n)
return;
*a = *o;
threePostorder(counter, size, a, b, o);
}
}
}
void postorder1(int size, NodePtr root){
if(root == NULL)
return;
printf("Postorder:\t");
NodePtr a = NULL;
NodePtr b = malloc(sizeof(Node));
b = root;
NodePtr o = NULL;
int i = 0;
onePostorder(&i, &size, &a, &b, &o);
printf("%c", root->data);
printf("\n");
}
NodePtr createNode(char val){
NodePtr x = malloc(sizeof(Node));
if(x == NULL){
printf("Overflow\n");
}
else{
x->data = val;
x->llink = NULL;
x->rlink = NULL;
x->tag = 0;
}
return x;
}
int isValidSequence(char *array[3], int size){
int ones = 0;
int zeroes = 0;
int i;
if(array[2][size-1] == '1'){
printf("INVALID SEQUENCES!\nLast token not the last sibling\n");
return -1;
}
for(i = 0; i < size; i++){
if(array[0][i] == '1'){
ones++;
if(ones >= 1)
array[0][i] = ones + 48;
//printf("array[0][i] = %c\n", array[0][i]);
}
if(array[2][i] == '0')
zeroes++;
}
//printf("1: %d\t0: %d\n", ones, zeroes);
if((zeroes - 1) != ones){
printf("INVALID SEQUENCES!\nUnbalanced number of ones in LTAG and zeroesin RTAG sequence (excluding last token).\n");
return -1;
}
else if((zeroes - 1) == ones)
return 1;
}
int getIndex(char value, char *array[3], int size){
int zero = 0;
int i;
for(i = 0; i < size; i++){
if(array[2][i] == '0'){
zero++;
//printf("index: %d\tvalue: %d\n", i, (value)-48);
if(zero + 48 == value){
//printf("index: %d\n", i+1);
return (i + 1);
}
}
}
return -1;
}
int firstNotDone(int doneLson[], int doneRson[], int size){
int i;
for(i = 0; i < size; i++)
if((doneLson[i] < 1) || (doneRson[i] < 1))
return i;
return -1;
}
void createTree(int size, char *array[3], NodePtr *root){
int i;
int currentIndex = 0;
int lsonIndex;
int isDoneLson[size];
int isDoneRson[size];
NodePtr node[size];
for(i = 0; i < size; i++){
isDoneLson[i] = 0;
isDoneRson[i] = 0;
node[i] = createNode(array[1][i]);
}
//int k = 0;
do{
while((array[2][currentIndex] == '1') && (isDoneRson[currentIndex] < 1)){
//printf("has siblings\n");
node[currentIndex]->rlink = node[currentIndex + 1];
isDoneRson[currentIndex]++;
currentIndex++;
}
isDoneRson[currentIndex]++;
//printf("current: %c\tcurrentIndex = %d\tlson = %d\trson = %d\n", array[1][currentIndex], currentIndex, isDoneLson[currentIndex], isDoneRson[currentIndex]);
//test siblings
NodePtr newNode = malloc(sizeof(Node));
newNode = node[currentIndex];
while(newNode != NULL){
//printf("seq: %c\n", newNode->data);
newNode = newNode->rlink;
}
currentIndex = firstNotDone(isDoneLson, isDoneRson, size);
//printf("current: %c\tcurrentIndex = %d\tlson = %d\trson = %d\n", array[1][currentIndex], currentIndex, isDoneLson[currentIndex], isDoneRson[currentIndex]);
if(array[0][currentIndex] != '0'){
//printf("has lson\n");
lsonIndex = getIndex(array[0][currentIndex], array, size);
//printf("lson of %c is %c\n", array[1][currentIndex], array[1][lsonIndex]);
node[currentIndex]->llink = node[lsonIndex];
}
isDoneLson[currentIndex]++;
//printf("current: %c\tcurrentIndex = %d\tlson = %d\trson = %d\n", array[1][currentIndex], currentIndex, isDoneLson[currentIndex], isDoneRson[currentIndex]);
isDoneLson[currentIndex]++;
currentIndex = firstNotDone(isDoneLson, isDoneRson, size);;
//printf("current: %c\tcurrentIndex = %d\tlson = %d\trson = %d\n", array[1][currentIndex], currentIndex, isDoneLson[currentIndex], isDoneRson[currentIndex]);
//k++;
}while(currentIndex != -1);
/*
for(i = 0; i < size; i++){
printf("Node[%d]: %c\t", i, node[i]->data);
if(node[i]->llink != NULL)
printf("llink: %c\t", node[i]->llink->data);
if(node[i]->rlink != NULL)
printf("rlink: %c\t", node[i]->rlink->data);
printf("\n");
}
**/
root = &node[0];
preorder1(size, node[0]);
postorder1(size, node[0]);
printf("\n");
}
void file(FILE *ptr, char *array[3], NodePtr *root){
char c;
int i = 0;
int j = 0;
int initSize = N;
int k;
int n;
array[0] = malloc(initSize);
do{
c = fgetc(ptr);
if(c == '\n'){
n = j;
j = 0;
break;
}
else{
if(j == (initSize - 1)){
initSize = initSize + N;
array[0] = realloc(array[0], initSize);
}
array[0][j] = c;
j++;
}
}while(1);
array[1] = malloc(n);
fscanf(ptr, "%s", array[1]);
array[2] = malloc(n);
fscanf(ptr, "%s", array[2]);
//print array
printSequence(array, n);
int isValid = isValidSequence(array, n);
if(isValid == 1){
createTree(n, array, root);
}
c = fgetc(ptr);
if(c == EOF){
printf("END\n");
fclose(ptr);
}
else{
c = fgetc(ptr);
file(ptr, array, root);
fclose(ptr);
}
}
void insertLson(NodePtr *father, NodePtr lson){
NodePtr x = malloc(sizeof(Node));
NodePtr *y;
x = (*father)->llink;
while(x != NULL){
x = x->llink;
}
y = &x;
x = lson;
printf("x = %c\n", x->data);
}
void type(char *array[3], NodePtr *root){
int lines = 0;
char c = getchar();
int n = 0;
int size;
int initSize = N;
array[0] = malloc(initSize);
c = getchar();
do{
if(c == '\n'){
size = n;
break;
}
else{
if(n == (initSize - 1)){
initSize = initSize + N;
array[0] = realloc(array[0], initSize);
}
array[0][n] = c;
n++;
}
c = getchar();
}while(1);
array[1] = malloc(size);
array[2] = malloc(size);
scanf("%s", array[1]);
scanf("%s", array[2]);
printSequence(array, n);
// printf("%s\t%s\t%s\n", array[0], array[1], array[2]);
// printf("%sdafi\n", array[0]);
int isValid = isValidSequence(array, size);
if(isValid == 1){
//printSequence(array, n);
//printf("isvalid\nsize: %d\n", n);
createTree(n, array, root);
}
c = getchar();
if(c == EOF){
printf("END\n");
return;
}
else{
c = getchar();
type(array, root);
}
}
int tree(){
NodePtr *root = NULL;
char *array[3];
int *size;
char filename[50];
int choice;
printf("Choose input:\n1. Keyboard\n2. File\n");
scanf("%d", &choice);
switch(choice){
case 1:
printf("Type input\n");
type(array, root);
break;
case 2:
printf("Type filename\n");
scanf("%s", filename);
FILE* ptr = fopen(filename, "r");
file(ptr, array, root);
break;
default:
printf("Invalid choice\n");
break;
}
}
int main(void){
tree();
return 0;
}

Related

Segmentation fault in hash table when inserting in linked list

I want to store passwords imput by user in a hash table by how strong the password is. After reading first password, it has to be inserted in the hash table and than go back for reading password. Segmentation fault occurs after first iteration.
The insertion function is basically an insertion in a linked list, what could be wrong there ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Node{
char* str;
struct Node* next;
};
int procent(char* str){
char aux;
for(int i = 0; i < strlen(str)-1; i++){
for(int j = i+1; j < strlen(str); j++){
if(str[i] > str[j]){
aux = str[i];
str[i] = str[j];
str[j] = aux;
}
}
}
int count = 1, chr = str[0];
for(int i = 0; i < strlen(str); i++){
if(str[i] != chr){
count++;
chr = str[i];
}
}
return count;
}
int hash_function(char* str){
int len = strlen(str), index;
if(len < 5){
index = 0;
}
else if(index >= 5 && index < 8){
index = 1;
}
else if(index >= 8 && index < 12){
index = 2;
}
else{
index = 3;
}
float rap = procent(str)/strlen(str);
if(rap < 0.5 && index > 0){
index--;
}
else if(rap > 0.5 && index < 3){
index++;
}
return index;
}
void insert(struct Node** head, char* str){
printf("Error");
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
strcpy(new_node->str, str);
new_node->next = NULL;
if(*head == NULL){
*head = new_node;
return;
}
else{
struct Node* last_node = *head;
while(last_node->next != NULL){
last_node = last_node->next;
}
last_node->next = new_node;
}
}
int main(){
struct Node *H[4];
for(int i = 0; i < 4; i++){
H[i] = NULL;
}
int raspuns, rap;
char pass[20];
while(1){
printf("Mai citesti ? 1-da/0-nu: ");
scanf("%d",&raspuns);
if(raspuns == 1){
printf("Parola: ");
scanf("%s", pass);
rap = procent(pass)/strlen(pass);
insert(&H[rap], pass);
}
else{
break;
}
}
for(int i = 0; i < 4; i++){
switch(i){
case 0:{printf("Foarte slabe: "); break;}
case 1:{printf("Slabe: "); break;}
case 2:{printf("Puternice: "); break;}
case 3:{printf("Foarte puternice: "); break;}
default: break;
}
while(H[i] != NULL){
printf("%s", H[i]->str);
H[i] = H[i]->next;
}
printf("\n");
}
return 0;
}

date structure and linked list printing problem

I am trying to creat a linked list in c language,
the code compiles with no error but when I run it , it won't run.
the data structure is a task which contains the label it's number, duration , number of linked tasks which will be put in an array and a pointer to the next task.
here's my code and the test code
#include <stdio.h>
#include <stdlib.h>
typedef struct tache { //linked listes structure
char label;
int num; //task number
int dure;
int *inter;
int n; //nombre d'antécedents
struct tache * suivant;
}strTache,*pTask;
pTask creerVide(){ //créer une tache vide
return NULL;
}
pTask firstTask(int d){
//créer la première tache qui prend la durée en argument
pTask first = (strTache*)(malloc(sizeof(strTache)));
first->num = 1;
first->suivant = NULL;
first->label = 'A';
first->dure = d;
first->n = 0;
return first;
}
Bool vide(pTask t){return t==NULL;} //check if a liste of tasks is empty this is predefined in a header included in the program
pTask ajouteTask(pTask t, int d){
pTask new = (strTache*)(malloc(sizeof(strTache)));
if(vide(t)){
new = firstTask(d);
t->suivant = new;
}else
{
pTask parc = t;
while(parc->suivant != NULL){parc=parc->suivant;}
new->num = parc->num+1;
new->label = parc->label+1;
new->suivant = parc->suivant;
parc->suivant = new;
new->dure=d;
}
return new;
}
void ajouteInter(pTask p,int numero, int taille, int tab[]){
int i,j;
pTask move = p;
while(move->suivant!=NULL){
if(move->num != numero){
move=move->suivant;
}//fin if
else
{
move->inter = (int*) malloc(taille*sizeof(int));
move->n = taille;
}//fin else
}//fin while
for(i=0;i<taille;i++){
move->inter[i] = tab[i];
}//fin for
}//fin function
void affichmat2(pTask p){
int i = 0;
pTask parc = p;
while(parc!= NULL){
printf("la tache %c a %d antécédents : ",parc->label,parc->n);
for(int j=0;j<parc->n;j++){
printf("%d ",parc->inter[j]);
}
printf("\n");
parc=parc->suivant;
i++;
}
free(parc);
}
int main()
{
int b[1] = {1};
int c[2] = {1,2};
//pTask t1 = creerVide();
pTask t1 = firstTask(2);
pTask t2,t3;
t2 = ajouteTask(t1,3);
t3 = ajouteTask(t2,4);
ajouteInter(t2,2,1,b);
ajouteInter(t3,3,2,c);
affichmat2(t1);
return 0;
}
I have made some changes thanks to your advice:
the function ajoutetask which called now addtask:
,,,
pTask addTask(pTask t, int d){
pTask new;
if(vide(t)){
new = firstTask(d);
new->suivant = t;
}else
{
new = (strTache*)(malloc(sizeof(strTache)));
pTask parc = t;
while(parc->suivant != NULL){parc=parc->suivant;}
new->num = parc->num+1;
new->label = parc->label+1;
new->suivant = parc->suivant;
parc->suivant = new;
new->dure=d;
}
return new;
}
,,,
the function ajouteinter which called now add antecedent:
void addAntecedent(pTask p,int num, int size, int b[]){
pTask search = p;
while(search->num !=num){
search = search->suivant;
}
search->inter = (int*)malloc(sizeof(int)*size);
search->n = size;
for(int i = 0;i<size;i++){
search->inter[i] = b[i];
}
}
the changes to the test file :
int main (){
int b[1] = {1};
int c[2] = {1,2};
pTask t1 = firstTask(2);
pTask t2,t3;
t2 = addTask(t1,3);
t3 = addTask(t1,4);
addAntecedent(t1,2,1,b);
addAntecedent(t1,3,2,c);
affichmat2(t1);
return 0;
}
the code works properly now
the result :
la tache A a 0 antécédents :
la tache B a 1 antécédents : 1
la tache C a 2 antécédents : 1 2
For starters use English words for identifiers.
Your code does not make a sense.
Consider for example the function ajouteTask
pTask ajouteTask(pTask t, int d){
pTask new = (strTache*)(malloc(sizeof(strTache)));
if(vide(t)){
new = firstTask(d);
t->suivant = new;
//...
If the pointer t is equal to NULL (that is when the function vide returns 1) then 1) the function invokes undefined behavior due to this statement
t->suivant = new;
and 2) it produces a memory leak because at first a memory was allocated and its address was assigned to the pointer new
pTask new = (strTache*)(malloc(sizeof(strTache)));
and then the pointer was reassigned
new = firstTask(d);
Or within the function ajouteInter you have an infinite while loop if move->num is equal to numero
void ajouteInter(pTask p,int numero, int taille, int tab[]){
int i,j;
pTask move = p;
while(move->suivant!=NULL){
if(move->num != numero){
move=move->suivant;
}//fin if
else
{
move->inter = (int*) malloc(taille*sizeof(int));
move->n = taille;
}//fin else
}//fin while
//...
So what you need is to rework your code and if there will be problems ask a new question.
Click here
https://uniblogsp.blogspot.com/2022/05/link-list-implementation-in-c-insertion.html
#include <stdio.h>
#include <stdlib.h>
typedef struct intnode
{
int data;
struct intnode *next;
} intnode;
intnode *create(int n)
{
intnode *head, *q, *newnode;
head = (intnode *)malloc(sizeof(intnode));
scanf("%d", &head->data);
head->next = NULL;
q = head;
for (int i = 0; i < n - 1; i++)
{
newnode = (intnode *)malloc(sizeof(intnode));
scanf("%d", &newnode->data);
newnode->next = NULL;
q->next = newnode;
q = newnode;
}
return head;
}
void printList(intnode *head)
{
intnode *temp;
temp = head;
while (head != NULL)
{
printf("%d", head->data);
head = head->next;
printf("\n");
}
head = temp;
}
void insertList(intnode *head, int i, intnode *t)
{
intnode *r, *x;
if (i == 0)
{
t->next = head;
head = t;
return;
}
r = head;
for (int j = 1; (j < i - 1) && (r != NULL); j++)
{
r = r->next;
}
if ((r == NULL) && (i > 0))
{
return;
}
x = r;
t->next = x->next;
x->next = t;
return;
}
void deleteList(intnode *head, int i)
{
intnode *y, *x;
y = head;
if (i == 0)
{
head = head->next;
free(y);
return;
}
x = y->next;
for (int j = 1; (j < i) && (x != NULL); i++)
{
y = x;
x = x->next;
}
if ((x == NULL) && (i > 0))
{
return;
}
y->next = x->next;
x->next = NULL;
free(x);
return;
}
int main()
{
int n, l;
printf("Enter the no of nodes: \n");
scanf("%d", &n);
printf("Enter the elements of nodes: \n");
intnode *p = create(n);
printf("Nodes are: \n");
printList(p);
printf("If you want to insert node then press 1 and in case of delete node press 0 : \n");
int ans;
scanf("%d", &ans);
if (ans == 1)
{
printf("In what positiomn you want to insert the node ??\n");
scanf("%d", &l);
intnode *a;
a = (intnode *)malloc(sizeof(intnode));
printf("Enter the node data :\n");
scanf("%d", &a->data);
a->next = NULL;
insertList(p, l, a);
printf("After insertion the list is : \n");
printList(p);
}
else
{
printf("In what positiomn you want to delete the node ??\n");
scanf("%d", &l);
deleteList(p, l);
printf("After deletion the list is : \n");
printList(p);
}
return 0;
}

Sparse Matrix with linked lists

I'm trying to create a sparse matrix in C using linked lists. My professor gave the file.h structs, a list of the functions and what they should do and told us to "work with it".
To resume everything, my code does not work, it stops working when I try to insert an element (calling ins_elem()) and returning weird number when calling soma_elem_coluna() and soma_elem_linha().
I've put the whole code below but the issue is really within the functions specified above (and soma_const() as I can't test it without inserting an element).
The logic I used is to create a matrix as in the image below (with numbers instead of characters)
[
Don't mind the weird typing, some words are in Portuguese.
(C = column and L = row)
this is my file.h:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINES 4
#define COLUM 4
typedef struct Node{
int Val, L, C;
struct Node *down, *right;
}Node;
typedef struct{
Node *L[LINES], *C[COLUM];
}matriz;
void cria_matriz(matriz* m); // creates matrix
void ins_elem(matriz* m, int e, int l, int c); // insert element e into lxc
void soma_const(matriz* m, int e, int l, int c); // add value e to existing lxc
int soma_elem_linha(matriz *m, int l); // sums all the values in row l
int soma_elem_coluna(matriz *m, int c); // sums all the values in column c
void imp(matriz *m); // prints the matrix
my file.c
#include "file.h"
void cria_matriz(matriz* m)
{
int i;
for(i=0;i<LINES;i++) //initializes headrows
{
m->L[i]->down = NULL;
m->L[i]->right = NULL;
m->L[i]->C = -1;
m->L[i]->L = -1;
}
for(i=0;i<COLUM;i++) //initializes headcolumns
{
m->C[i]->down = NULL;
m->C[i]->right = NULL;
m->C[i]->C = -1;
m->C[i]->L = -1;
}
}
void ins_elem(matriz *m, int e, int l, int c)
{
Node* auxLine; // move through row
Node* auxCol; // move through column
auxLine = &m->L[l];
auxCol = &m->C[c];
while(auxLine->right != NULL && auxLine->right->C < c) //find correct pos in row
{
auxLine = auxLine->right;
}
while(auxCol->down != NULL && auxCol->down->L < c) //find correct pos in column (error happens here)
{
auxCol = auxCol->down;
}
Node* novo = malloc(sizeof(Node));
novo->Val = e;
novo->C = c;
novo->L = l;
novo->down = auxCol->down;
auxCol->down = novo;
novo->right = auxLine->right;
auxLine->right = novo;
}
void soma_const(matriz *m, int e, int l, int c)
{
Node* aux = &m->C[c];
while(aux->down != NULL && aux->L < l)
aux = aux->down;
aux->Val+=e;
}
int soma_elem_coluna(matriz *m, int c)
{
int sum = 0;
Node* aux = &m->C[c];
if(aux->down == NULL)
return 0;
while(aux->down != NULL)
{
aux = aux->down;
sum += aux->Val;
}
return sum;
}
int soma_elem_linha(matriz *m, int l)
{
int sum = 0;
Node* aux = &m->L[l];
if(aux->right == NULL)
return 0;
while(aux->right != NULL)
{
aux = aux->right;
sum += aux->Val;
}
return sum;
}
void imp(matriz *m)
{
Node* aux;
int i, j;
for(i=0;i<LINES;i++)
{
aux = &m->L[i];
for(j=0;j<COLUM;j++)
{
if(aux->C == j)
{
printf("%d ",aux->Val);
aux = aux->right;
}
else
{
printf("0 ");
}
}
printf("\n");
}
}
my main.c:
#include "file.h"
int main()
{
struct matriz* M = (matriz*)malloc(sizeof(matriz));
int i,e,c,l,result;
char str[20];
for(i=0;i<5;i++) // this is temporary and another issue, how I make a while that
{ // only stops when user (a bot actually) presses enter?
scanf(" %s",str);
if(!strcmp(str,"cria_matriz"))
{
cria_matriz(M);
}
else if(!strcmp(str,"ins_elem"))
{
scanf("%d %d %d",&e,&l,&c);
ins_elem(M,e,l,c);
}
else if(!strcmp(str,"soma_const"))
{
scanf("%d %d %d",&e,&l,&c);
soma_const(M,e,l,c);
}
else if(!strcmp(str,"soma_elem_linha"))
{
scanf("%d",&l);
result = soma_elem_linha(M,l);
printf("%d\n",result);
}
else if(!strcmp(str,"soma_elem_coluna"))
{
scanf("%d",&c);
result = soma_elem_coluna(M,c);
printf("%d\n",result);
}
else if(!strcmp(str,"imp"))
{
imp(M);
}
}
return 0;
}
Your files didn't compile without warnings as there were lots of pointer and other problems with the code. I've worked over your code to clean up the warnings but I'm not in a position to test the logic -- you'll have to do that:
file.c
#include "file.h"
void cria_matriz(matriz *m)
{
for (int i = 0; i < LINES; i++) // initializes headrows
{
m->L[i] = malloc(sizeof(Node));
m->L[i]->down = NULL;
m->L[i]->right = NULL;
m->L[i]->C = -1;
m->L[i]->L = -1;
m->L[i]->Val = 0;
}
for (int i = 0; i < COLUM; i++) // initializes headcolumns
{
m->C[i] = malloc(sizeof(Node));
m->C[i]->down = NULL;
m->C[i]->right = NULL;
m->C[i]->C = -1;
m->C[i]->L = -1;
m->C[i]->Val = 0;
}
}
void ins_elem(matriz *m, int e, int l, int c)
{
Node *auxLine = m->L[l]; // move through row
Node *auxCol = m->C[c]; // move through column
while (auxLine->right != NULL && auxLine->right->C < c) // find correct pos in row
{
auxLine = auxLine->right;
}
while (auxCol->down != NULL && auxCol->down->L < c) // find correct pos in column (error happens here)
{
auxCol = auxCol->down;
}
Node *novo = malloc(sizeof(*novo));
novo->Val = e;
novo->C = c;
novo->L = l;
novo->down = auxCol->down;
auxCol->down = novo;
novo->right = auxLine->right;
auxLine->right = novo;
}
void soma_const(matriz *m, int e, int l, int c)
{
Node *aux = m->C[c];
while (aux->down != NULL && aux->L < l)
{
aux = aux->down;
}
aux->Val += e;
}
int soma_elem_coluna(matriz *m, int c)
{
Node *aux = m->C[c];
if (aux->down == NULL) {
return 0;
}
int sum = 0;
while (aux->down != NULL)
{
aux = aux->down;
sum += aux->Val;
}
return sum;
}
int soma_elem_linha(matriz *m, int l)
{
Node *aux = m->L[l];
if (aux->right == NULL) {
return 0;
}
int sum = 0;
while (aux->right != NULL)
{
aux = aux->right;
sum += aux->Val;
}
return sum;
}
void imp(matriz *m)
{
for (int i = 0; i < LINES; i++)
{
Node *aux = m->L[i];
for (int j = 0; j < COLUM; j++)
{
if (aux->C == j)
{
printf("%d ", aux->Val);
aux = aux->right;
}
else
{
printf("0 ");
}
}
printf("\n");
}
}
main.c
#include "file.h"
int main()
{
matriz *M = malloc(sizeof(*M));
int e, c, l;
char str[32];
for (int i = 0; i < 5; i++) // this is temporary and another issue, how I make a while that
{ // only stops when user (a bot actually) presses enter?
(void) scanf(" %s", str);
if (strcmp(str, "cria_matriz") == 0)
{
cria_matriz(M);
}
else if (strcmp(str, "ins_elem") == 0)
{
scanf("%d %d %d", &e, &l, &c);
ins_elem(M, e, l, c);
}
else if (strcmp(str, "soma_const") == 0)
{
(void) scanf("%d %d %d", &e, &l, &c);
soma_const(M, e, l, c);
}
else if (strcmp(str, "soma_elem_linha") == 0)
{
(void) scanf("%d", &l);
int result = soma_elem_linha(M, l);
printf("%d\n", result);
}
else if (strcmp(str, "soma_elem_coluna") == 0)
{
scanf("%d", &c);
int result = soma_elem_coluna(M, c);
printf("%d\n", result);
}
else if (strcmp(str,"imp") == 0)
{
imp(M);
}
}
free(M);
return 0;
}
The biggest issue was that you kept making pointers to things that were already pointers. Also, you initialized data that you hadn't actually allocated. You didn't initialize some data that you subsequently added onto. Finally, strcmp() isn't a boolean, don't use it as one.

Why this code doesn't update file?

this program create a file,write on the file, after read from that file, update data and then put the file's content into an array. When I run the code, it doesn't work right, in fact, all values printed except for Vet[i].squadra are zero. I debugged the code and I saw that AggiornaFile function resets to zero variable's values each time I use fseek and freed, so I think that fwrite update values into file with zeros.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define DIMMAX 4
#define DIMCAR 20
typedef char Stringa[DIMCAR];
typedef struct{
int vinte;
int perse;
int nulle;
} Partite;
typedef struct{
int subiti;
int effettuati;
} Goal;
typedef struct{
int squadra;
Partite partite;
Goal goal;
int punti;
} Nota;
typedef struct{
int squadra1;
int squadra2;
int goal1;
int goal2;
} Match;
void CreaFile(Stringa, int);
void DisputaMatch(Match *, int, int);
void AggiornaFile(Stringa, Match);
int CalcolaEsito(Match);
void DisputaFase(int, Stringa);
Nota CalcolaClassifica(Nota[], int, Stringa);
void ordina(Nota *, int);
void StampaClassifica(Nota[], int);
int calcolaNPartite(Nota);
void CreaFile(Stringa percorso, int valDati){
FILE *ptr;
Nota n;
int i;
ptr = fopen(percorso, "wb");
if(ptr ==NULL){
printf("File inesistente.\n");
}
else{
for(i=1; i<= valDati; i++){
n.partite.vinte = 0;
n.partite.perse = 0;
n.partite.nulle = 0;
n.goal.subiti = 0;
n.goal.effettuati = 0;
n.punti = 0;
n.squadra = i;
fwrite(&n, sizeof(Nota), 1, ptr);
}
fclose(ptr);
}
}
void DisputaMatch(Match *incontro, int S1, int S2){
int rand1,rand2;
incontro->squadra1 = S1;
incontro->squadra2 = S2;
rand1 = rand() % 5;
rand2 = rand() % 5;
incontro->goal1 = rand1;
incontro->goal2 = rand2;
}
void AggiornaFile(Stringa percorso, Match incontro){
FILE *ptr;
Nota n;
int esito;
ptr = fopen(percorso, "rb+");
if(ptr == NULL){
printf("File inesistente.\n");
}
else{
fseek(ptr, incontro.squadra1*sizeof(Nota), SEEK_SET);
fread(&n, sizeof(Nota), 1, ptr);
n.goal.effettuati += incontro.goal1;
n.goal.subiti += incontro.goal2;
esito = CalcolaEsito(incontro);
switch(esito){
case 0:
n.partite.nulle++;
n.punti += 1;
break;
case 1:
n.partite.vinte++;
n.punti += 3;
break;
case 2:
n.partite.perse++;
break;
}
fwrite(&n, sizeof(Nota),1, ptr);
fseek(ptr, incontro.squadra2*sizeof(Nota), SEEK_SET);
fread(&n, sizeof(Nota), 1, ptr);
n.goal.effettuati += incontro.goal2;
n.goal.subiti += incontro.goal1;
switch(esito){
case 0:
n.partite.nulle++;
n.punti += 1;
break;
case 1:
n.partite.perse++;
break;
case 2:
n.partite.vinte++;
n.punti += 3;
break;
}
fwrite(&n, sizeof(Nota),1, ptr);
fclose(ptr);
}
}
int CalcolaEsito(Match incontro){
int esito;
if(incontro.goal1 == incontro.goal2){
esito = 0;
}
else if(incontro.goal1 > incontro.goal2){
esito = 1;
}
else{
esito = 2;
}
return esito;
}
void DisputaFase(int valDati, Stringa percorso){
Match incontro;
int i,j;
for(i=1; i<=valDati; i++){
for(j=1; j<=valDati; j++){
if( j!= i){
DisputaMatch(&incontro, i, j);
AggiornaFile(percorso, incontro);
}
}
}
}
Nota CalcolaClassifica(Nota Vet[], int dim, Stringa percorso){
FILE *ptr;
Nota n;
int i = 0;
ptr = fopen(percorso, "rb");
if(ptr == NULL){
printf("File inesistente.\n");
}
else{
while(!feof(ptr)){
fread(&n, sizeof(Nota),1,ptr);
Vet[i] = n;
i++;
}
fclose(ptr);
}
ordina(Vet, dim);
return Vet[0];
}
void ordina(Nota *Vet, int dim){
int i,j;
int min;
Nota temp;
for(i=0; i<dim-1; i++){
min = i;
for(j=i+1; j<dim; j++){
if(Vet[min].punti < Vet[j].punti){
min = j;
}
}
if(min != i){
temp = Vet[min];
Vet[min] = Vet[i];
Vet[i] =temp;
}
}
}
void StampaClassifica(Nota Vet[], int dim){
int i,j;
printf("\n%s%15s%15s%18s%15s%15s%15s%15s\n", "Squadra", "Punteggio", " PartiteGiocate", "Vinte", "Perse", "Nulle", "Gsubiti", "Gfatti");
for(i=0; i<dim; i++){
printf("%7d%15d%15d%18d%15d%15d%15d%15d\n", Vet[i].squadra, Vet[i].punti, calcolaNPartite(Vet[i]), Vet[i].partite.vinte, Vet[i].partite.perse, Vet[i].partite.nulle,Vet[i].goal.subiti, Vet[i].goal.effettuati);
}
}
int calcolaNPartite(Nota nota){
int giocate;
giocate = nota.partite.nulle + nota.partite.perse + nota.partite.vinte;
return giocate;
}
int main(int argc, char *argv[]) {
FILE *ptr;
char percorso[300] = "C:\\file.dat";
Nota Vet[DIMMAX];
srand(time(NULL));
CreaFile(percorso, DIMMAX);
DisputaFase(DIMMAX, percorso);
CalcolaClassifica(Vet, DIMMAX, percorso);
StampaClassifica(Vet, DIMMAX);
return 0;
}
Note that fread and fwrite both advance the file pointer.
When wanting to read/modify/write in AggiornaFile you must fseek again before the write.
Also, be sure to use 0-based record indexing.

Breadth first search suddenly crashes

I'm trying to implement BFS on a 400x200 grid that inputs a text file with an ordered starting pair and an ordered ending pair. I used a queue to keep track of opened nodes and an array to keep tracked of closed nodes. My program keeps crashing at random on the same input while checking for opened nodes in the queue.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
typedef struct Node Node;
typedef struct Qnode Qnode;
struct Node{
Node* up;
Node* down;
Node* left;
Node* right;
int xpos;
int ypos;
int marked;
};
struct Qnode{
Qnode* next;
Node* Gnode;
};
Qnode* front = NULL;
Qnode* rear = NULL;
int queuesize = 0;
int solutioncost = 0;
Node* closednodes[80000];
int nodesclosed = 0;
void enqueue(Node* node){
if (queuesize == 0){
rear = (Qnode*)malloc(sizeof(Qnode*));
rear->Gnode = node;
rear->next = NULL;
front = rear;
}
else{
Qnode* temp = (Qnode*)malloc(sizeof(Qnode*));
rear->next = temp;
temp->Gnode = node;
temp->next = NULL;
rear = temp;
}
queuesize++;
}
Node* dequeue(){
Qnode* temp = front;
if (queuesize == 0){
printf("Error!");
}
else{
Node* temp1 = front->Gnode;
temp = temp->next;
free(front);
front = temp;
queuesize--;
return temp1;
}
}
Node* generate(int x, int y){
printf("Generating node (%d,%d)...\n", x, y);
if ((x >0 && x <=400) && (y >0 && y <=200)){
Node* temp = (Node*)malloc(sizeof(Node));
temp->xpos = x;
temp->ypos = y;
temp->marked = 0;
temp->up = NULL;
temp->down = NULL;
temp->left = NULL;
temp->right = NULL;
return temp;
}
else{
printf("Invalid starting point! \n");
}
}
void expand(Node* node, int xend, int yend){
int flag = 0;
closednodes[nodesclosed] = node;
nodesclosed++;
dequeue();
if(node->marked == 1){
printf("already expanded");
}
else{
printf("Expanding node (%d, %d)...\n", node->xpos, node->ypos);
node->marked = 1;
if (node->xpos == xend && node->ypos == yend){
printf("Node reached!");
queuesize = 0;
return;
}
if (node->xpos-1 >0 && node->left == NULL){
int k = 0;
int j = 0;
Qnode* temp2 = front;
printf("%d", queuesize);
for(k; k<queuesize; k++){
int xx = temp2->Gnode->xpos;
int yy = temp2->Gnode->ypos;
printf("%d, %d,\n", xx, yy);
if (xx == node->xpos-1 && yy == node->ypos)
flag = 1;
temp2 = temp2->next;
}
for(j; j<nodesclosed; j++){
int xx = closednodes[j]->xpos;
int yy = closednodes[j]->ypos;
if (xx == node->xpos-1 && yy == node->ypos)
flag = 1;
}
if (flag == 0){
node->left = generate(node->xpos-1, node->ypos);
node->left->right = node->left;
enqueue(node->left);
}
else{
printf("(%d, %d) not generated.\n", node->xpos-1, node->ypos);
flag = 0;
}
}
if (node->xpos+1 <=400 && node->right ==NULL){
int k = 0;
int j = 0;
Qnode* temp2 = front;
for(k; k<queuesize; k++){
int xx = temp2->Gnode->xpos;
int yy = temp2->Gnode->ypos;
printf("%d, %d,\n", xx, yy);
if (xx == node->xpos+1 && yy == node->ypos)
flag = 1;
temp2 = temp2->next;
}
for(j; j<nodesclosed; j++){
int xx = closednodes[j]->xpos;
int yy = closednodes[j]->ypos;
if (xx == node->xpos+1 && yy == node->ypos)
flag = 1;
}
if (flag == 0){
node->right = generate(node->xpos+1, node->ypos);
node->right->left = node->right;
enqueue(node->right);
}
else{
printf("(%d, %d) not generated.\n", node->xpos+1, node->ypos);
flag = 0;
}
}
if (node->ypos+1 <=200 && node->up ==NULL){
int k = 0;
int j = 0;
Qnode* temp2 = front;
printf("%d", queuesize);
for(k; k<queuesize; k++){
int xx = temp2->Gnode->xpos;
int yy = temp2->Gnode->ypos;
if (xx == node->xpos && yy == node->ypos+1)
flag = 1;
temp2 = temp2->next;
}
for(j; j<nodesclosed; j++){
int xx = closednodes[j]->xpos;
int yy = closednodes[j]->ypos;
if (xx == node->xpos && yy == node->ypos+1)
flag = 1;
}
if (flag ==0){
node->up = generate(node->xpos, node->ypos+1);
node->up->down = node->up;
enqueue(node->up);
}
else{
printf("(%d, %d) not generated.\n", node->xpos, node->ypos+1);
flag = 0;
}
}
if (node->ypos-1 >0 && node->down ==NULL){
int k = 0;
int j = 0;
Qnode* temp2 = front;
for(k; k<queuesize; k++){
int xx = temp2->Gnode->xpos;
int yy = temp2->Gnode->ypos;
printf("%d, %d,\n", xx, yy);
if (xx == node->xpos && yy == node->ypos-1)
flag = 1;
temp2 = temp2->next;
}
for(j; j<nodesclosed; j++){
int xx = closednodes[j]->xpos;
int yy = closednodes[j]->ypos;
if (xx == node->xpos && yy == node->ypos-1)
flag = 1;
}
if (flag ==0){
node->down = generate(node->xpos, node->ypos-1);
node->down->up = node->down;
enqueue(node->down);
}
else{
printf("(%d, %d) not generated.\n", node->xpos, node->ypos-1);
flag = 0;
}
}
printf("EXPANSION ENDS\n");
return;
}
}
int main(){
int x_start, y_start, x_end, y_end;
FILE *fp;
fp = fopen("testfile.txt", "r");
if (fp == NULL)
printf("Error printing output. \n");
else
fscanf(fp, "(%d,%d)\n", &x_start, &y_start);
fscanf(fp, "(%d,%d)\n", &x_end, &y_end);
printf("Starting point is (%d, %d)\n", x_start, y_start);
printf("Ending point is (%d, %d)\n", x_end, y_end);
Node* start = generate(x_start, y_start);
enqueue(start);
while(queuesize!=0){
expand(front->Gnode, x_end, y_end);
}
fclose(fp);
}
using testfile.txt
(1,1)
(50,50)
this input will cause the program to crash at random. I am suspecting I have a problem with my queue.
In the enqueue function, you should allocate the new nodes as (Qnode*)malloc(sizeof(Qnode)) (instead of (Qnode*)). The code you wrote allocates only the size of a pointer for each struct, so any write to such an object will stomp on some other object's memory.

Resources