Sparse Matrix with linked lists - c

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.

Related

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;
}

Hashcode of a string in C with Chaining

I have this assignment where I need to implement string hashcoding with chaining in c++ I,ve already tried it but with int data type only could anyone provide some guidance on how to do it? Should I use another hashcode function ??
I’ve already done the display insert function I still have to convert it to string and add three functions of hashcoding and apply it each time to a file and tht each line contain a random word of length from 3 to 30 characters and I have 10000 line which means 10000 words
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10 // prime number for size of array
#define h(x) (x % m) // h(x) = x mod m
// Node for List
typedef struct Node {
int val;
struct Node *next;
} Node;
//function's declaration
Node *fill_table(Node *table, int table_range, int number);
Node *insert(Node *table, int hash_index, int val);
void print_table(Node *table, int table_range);
int main() {
Node *table; // hashtable
int n, i, j, choice, search;
int hash_num, val;
// allocate table
table = (Node*) malloc(N * sizeof(Node));
// make table "heads" NULL
for (i = 0; i < N; i++) {
table[i].next = NULL;
}
printf("--h(x) = xmod%d--\n", N);
printf("\n\n");
while (1) {
printf("1.Insert random numbers\n");
printf("2.Show Hash Table\n");
printf("0.Exit Programm\n");
printf("\n--------\n");
printf("Choice: ");
scanf("%d",&choice);
switch (choice) {
case 0: break;
case 1:
// insert random numbers
printf("Lot to insert: ");
scanf("%d", &n);
table = fill_table(table, N, n);
printf("Filled HashTable with %d random values\n", n);
printf("\n--------\n");
break;
case 2:
// print hashtable
printf("-HASHTABLE-\n\n");
print_table(table, N);
printf("\n--------\n");
break;
}
}
return 0;
}
// FUNCTIONS
Node *fill_table(Node *table, int table_range, int number) {
int i;
int num;
for (i = 0; i < number; i++) {
num = rand() % 10000; // random number from 0 to 9999
table = insert(table, num % table_range, num);
}
return table;
}
void print_table(Node *table, int table_range) {
int i;
Node* cur;
for (i = 0; i < table_range; i++) { // for each list
if (table[i].next == NULL) { // if empty
printf("Table[%d] is empty!\n", i);
continue;
}
cur = table[i].next;
printf("Table[%d]", i);
while (cur != NULL) { // else print all the values
printf("->%d", cur->val);
cur = cur->next; //cur=cur+1;
}
printf("\n");
}
}
Node *insert(Node *table, int hash_index, int val) {
Node *nn, *cur;
nn = (Node*)malloc(sizeof(Node));
nn->val = val;
nn->next = NULL;
if (table[hash_index].next == NULL) {
table[hash_index].next = nn;
return table;
}
cur = table[hash_index].next;
while (cur->next != NULL) {
cur = cur->next; //cur=cur+1;
}
cur->next = nn;
return table;
}
hash

Parenthesis balance program crashing(c)

Good afternoon, i am trying to do a program that checks whether if a expression has its parentheses balanced or not but because of some problem that i can't quite find out the program is crashing, could somebody help me find a way so that the program works?
In
a * b - (2 + c)
Out
Correct
or
In
)3+b * (2-c)(
Out
Incorrect
The program should check only for parantheses and i am supposed to implement linear lists on the code.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SUCESSO 1 //Succes
#define FALHA -1 //Failure
#define CELULA_INVALIDA 0 //Invalid key
#define TAMANHO_MAXIMO 1000 //Max size
typedef struct{
char exp[1000];
unsigned int chave; //key
}celula; //node
typedef struct{
celula celulas[TAMANHO_MAXIMO]; //vector of nodes
unsigned int tamanho; //size of the list
}fila; //list
int criarFilaVazia(fila * ent){ //create an empty list
ent->tamanho = 0;
return(SUCESSO);
}
int insFinal(fila * ent, celula node){ //put a node on the end of the list
unsigned int i;
celula aux;
if(ent->tamanho == TAMANHO_MAXIMO){
return(FALHA);
}
else{
ent->celulas[ent->tamanho] = node;
ent->tamanho++;
return(SUCESSO);
}
}
void mostrarCelula(celula ent){ //show node
printf("%s \n", ent.exp);
}
void mostrarFila(fila ent){ //show entire list
unsigned int i;
if(ent.tamanho == 0){
printf("Fila vazia");
}
else{
printf("A fila possui %u element \n", ent.tamanho);
for(i=0; (i < ent.tamanho); i++){
printf("Elemento %u \n \n", (i+1));
mostrarCelula(ent.celulas[i]);
}
}
}
int main(){
int i, j;
fila exp;
celula aux;
scanf("%s", &aux.exp);
getchar();
aux.chave = 0;
insFinal(&exp, aux);
for(i = 0; i < strlen(exp.celulas[0].exp); i++){//checks all the array
if(exp.celulas[0].exp[i] == '('){//if there is an opening
for(j = i; j < strlen(exp.celulas[0].exp); j++){
if(exp.celulas[0].exp[j] == ')'){//should be and ending
exp.celulas[0].exp[i] = 0;//removes if balanced
exp.celulas[0].exp[j] = 0;
}
}
}
}
//checks for remaining parentheses and prints the output
for(i = 0; i < strlen(exp.celulas[0].exp); i++){
if(exp.celulas[0].exp[i] == '(' || exp.celulas[0].exp[i] == ')'){
printf("Incorreta"); //incorrect
}
else{
printf("Correta"); //correct
}
}
return 0;
}
[enter image description here][1]
Error message: https://i.stack.imgur.com/aeSn5.png
it says ex06 stopped working
Your program is crashing inside insFinal because the ent parameter passed in from main has uninitialized data. Hence, undefined behavior. Ammend these two lines at the beginning of main:
fila exp;
celula aux;
With this:
fila exp = {0};
celula aux = {0};
That will zero-init both.
The thing I don't get is what all these data structures are used for. Nor do I understand the double-nested for loop for checking the balance. Checking for a balanced set of parentheses in an expression should be as simple as this:
int areParenthesesBalanced(const char* str)
{
int balance = 0;
int len = str ? strlen(str) : 0;
for (int i = 0; i < len; i++)
{
if (str[i] == '(')
{
balance++;
}
else if (str[i] == ')')
{
balance--;
if (balance < 0)
{
return 0;
}
}
}
return (balance == 0) ? 1 : 0;
}
int main() {
char str[1000];
scanf("%s", str);
if (areParenthesesBalanced(str))
{
printf("Incorreta\n");
}
else
{
printf("Correta\n");
}
return 0;
}

C - char** not printing correctly after being returned from function

I am trying to return a char** from a function to main so I can do stuff with it, but when I print it out it gives me random characters. I'm at a loss.
main VV
// ./main < data/filelist.txt
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hist.h"
int main(){
int count = 0;
int i;
char** files = read(&count);
displayList(files, count);
char** array = splitFiles(files, count);
printf("IN MAIN: array[0] - %s\n", array[0]);
Histogram* p;
printf("here\n");
int histArrayCount = calcHistogram(&array[0], &count, &p);
printf("here\n");
displayHistogram(p, histArrayCount);
printf("here\n");
}
hist.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hist.h"
int calcHistogram (char** a, int* count, Histogram** q) {
int i, k;
int j = 0;
int histArrayCount = 0;
Histogram* p = (Histogram*)malloc((*count) * sizeof(Histogram));
for (k = 0; k < *count; k++) {
p[k].num = "1";
p[k].freq = 0;
}
for (i = 0; i <= *count; i++) {
while ((strcmp(p[j].num, "1") != 0) && (strcmp(p[j].num, a[i]) != 0)) {
j++;
}
if (strcmp(p[j].num, "1") == 0) {
p[j].num = a[i];
p[j].freq = 1;
histArrayCount++;
}
else if ((strcmp(p[j].num, a[i]) == 0)) {
p[j].freq += 1;
}
else {
printf("ERROR\n");
}
j = 0;
}
*q = p;
return histArrayCount;
}
void displayHistogram (Histogram* p, int histArrayCount) {
int i;
for (i = 0; i < histArrayCount - 1; i++) {
printf("value %s: freq %d\n", p[i].num, p[i].freq);
}
printf("\n");
}
char** splitFiles(char** files, int count) {
int i;
char** array = (char**)malloc((count)*sizeof(char*));
FILE* fp;
int c = 0;
for(i = 0; i < count; i++) {
char buff[255];
fp = fopen(files[i], "r");
array[i] = fgets(buff, 255, (FILE*)fp);
printf("%d : %s\n", i, buff);
}
printf("array[0] = %s\n", array[0]);
return array;
}
void displayList(char** a, int c) {
int i;
for (i = 0; i < c; i++) {
printf("File %d: %s\n", i, a[i]);
}
printf("\n");
}
char** read(int* c){
int count = 0;
int i;
char** a = (char**)malloc(100*sizeof(char*));
for (i = 0; i< 100; i++) {
a[count] = (char*)malloc(100*sizeof(char));
count++;
}
count = 0;
int endOfFile = scanf("%s", a[count]);
while (endOfFile != EOF) {
count++;
endOfFile = scanf("%s", a[count]);
}
*c = count;
return a;
}
When I print the array at index 0 in here it gives me what is actually there, but when I do the same thing in main it does not. It gives me three random characters.
hist.h
typedef struct Histogram {
char* num;
int freq;
} Histogram;
char** read(int* c);
void displayList(char** a, int c);
int calcHistogram (char** a, int* c, Histogram** p);
void displayHistogram (Histogram* a, int histArrayCount);
char** splitFiles (char** files, int count);

Preorder Postorder Tree Traversal when RSON and LSON are given

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;
}

Resources