I have an array[4] where each index of the array has a singly linked list that holds the following information: name, size. The switch statement controls what index the information will go into according to the size of the party.
Problem: When trying to delete a node according to the size (user inputs) the node will not delete.
I know that all of the cases of deletion have the proper syntax but I cannot figure out why my node will not delete. Appreciate any help.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
char name[20];
int size;
struct node *next;
}node;
node* head[4]={NULL,NULL,NULL,NULL};
node* tail[4]={NULL,NULL,NULL,NULL};
//
// proto's
//
void add_party(int, char name[], int size);
void delete_party(char name[], int size);
void list_parties(void);
void change_p_size(char name[], int size);
//
// main function
//
int main()
{
int x;
while (1)
{
fflush(stdin);
printf("\n\nEnter 1 to add a party\nEnter 2 to remove a party\nEnter 3 for the list of the party\nEnter 4 to change party size.\nEnter 5 to quit.\n\n");
// user interface
scanf("%d",&x);
switch(x)
{
char name[20]; //local variables
int size;
case 1:
printf("\nParty Name: ");
scanf("%s", name);
printf("\nParty Size: ");
scanf("%d", &size);
if(size == 0)
{
printf("\nThat is not a valid command. Party not added!\n");
}
if(size >= 1 && size <= 2)
{
add_party(0, name, size);
}
else if(size >= 3 && size <= 4)
{
add_party(1, name, size);
}
else if(size >= 5 && size <= 6)
{
add_party(2, name, size);
}
else if(size >= 7)
{
add_party(3, name, size);
}
break;
case 2:
printf("\nSize of party to delete: ");
scanf("%i", &size);
delete_party(NULL, size);
break;
case 3:
list_parties();
break;
case 4:
change_partysize();
break;
case 5:
exit(0);
default:
continue;
}
}
}
//
//add function
//
void add_party(int h, char *name, int size)
{
//create a new node
int i=0;
int breaker = 0;
node *p;
node *new_item;
new_item = (node *)malloc(sizeof(node)); // allocate memory the size of the struct
strcpy(new_item->name,name);
new_item->size = size;
if(head[h] == NULL && tail[h] == NULL) // if an empty list, create a head and tail
{
head[h] = new_item;
tail[h] = head[h];
new_item->next = NULL;
return;
}
//traversal
for(i=0; i<4; i++)
{
p = head[i];
while(p != NULL)
{
//check that no repeating names. delete nodes that do have repeating names
if(strcmp(p->name,name) == 0)
{
printf("\nSorry, that name is already taken\n");
free(new_item);
return;
}
p = p->next; //go to the next node in the list
}
}
tail[h]->next = new_item;
new_item->next = NULL;
tail[h] = new_item;
}
//
//delete function
//
void delete_party(char *name, int size)
{
int i=0;
int breaker = 0;
node *p;
node *previous;
if(name != NULL)
{
for(i=0; i<4; i++)
{
p = previous = head[i]; //make sure previous trails behind head
while(p != NULL)
{
int c = (strcmp(p->name,name)==0);
if(c==0)
{
breaker = 1;
break;
}
else
previous = p;
p = p -> next;
}
if(breaker==1)
break;
}
}
else
{
int group = -1;
if(size == 1 || size == 2)
{
group = 0;
}
if(size == 3 || size == 4)
{
group = 1;
}
if(size == 5 || size == 6)
{
group = 2;
}
if(size >= 7)
{
group = 3;
}
for(i = group; i > -1; i--)
{
node *p = head[i];
node *previous = head[i];
while(p != NULL)
{
if(p <= size)
{
breaker = 1;
break;
}
else
{
previous = p;
p = p-> next;
}
}
if(breaker)
break;
}
}
if(p == NULL)
return;
if(head[i] == tail[i] && head[i] != NULL) // case 1, empty list
{
printf("\nList is empty!\n");
return;
}
else if(p == tail[i] && p == head[i]) // case 2, one element
{
head[i] = NULL;
tail[i] = NULL;
free(p);
}
else if(p == head[i]) // case 3, delete from the head
{
head[i] = head[i] -> next;
tail[i] = NULL;
free(p);
}
else if(p == tail[i]) // case 4, delete from tail
{
tail[i] = previous;
tail[i] -> next = NULL;
free(p);
}
else // case 5, delete from middle
{
previous -> next = p -> next;
free(p);
}
}
//
// list function
//
void list_parties(void)
{
int i = 0;
node *p=head;
for(i=0; i<4; i++)
{
p=head[i];
while(p != NULL)
{
printf("\n\n%s, %d\n\n", p->name, p->size);
p=p->next;
}
}
}
//
// change function
//
void change_partysize(char *name, int size)
{
int absolute_value = 0;
int comparison = 0;
int current_size = 0;
printf("\nWhat name is your party under?\n");
scanf("%s", name);
//check if the name
printf("\nWhat would you like to change the size to?\n");
scanf("%d", &size);
node *p;
while(p != NULL)
{
if(p->name == name) //new size falls into same range as the size coorelating to the name
{
current_size = p->size;
absolute_value = abs(size - current_size);
comparison = size - current_size;
if(current_size > 7 && size > 7)
{
current_size = size;
return;
}
else if(absolute_value >= 1)
{
//delete the node's value but not the name
delete_party(NULL, size);
//insert node with new name & dif size
add_party(NULL, name, size);
}
else
{
printf("\nYou did not enter a different party size\n");
return;
}
}
}
}
You're declaring new variables p and previous inside the for loop when you delete by size. So when the code after the loop uses these variables, it's using the uninitialized variables declared at the top of the function. Get rid of the declarations and just assign the variables.
Also, if (p <= size) appears to be a typo for if (p->size <= size). I'm surprised you didn't get a compiler warning for that.
You can also replace the if(breaker) check with a test in the for header.
for(i = group; !breaker && i > -1; i--)
{
p = head[i];
previous = head[i];
while(p != NULL)
{
if(p->size <= size)
{
breaker = 1;
break;
}
else
{
previous = p;
p = p-> next;
}
}
}
Related
I think the main problem lies with pointer also keeping in mind the restriction that I can't return node type pointer. Please help me find out where am I doing the mistake.
I have commented the other operations of this code and trying to solve this one first. So the code has switch statements and the irrelevant functions calls have been added as part of comment for now.
#include <stdio.h>
#include <stdlib.h>
typedef struct tree { //definition of structure
int info;
//char *Name;
struct tree *left;
struct tree *right;
} tree;
int main()
{
int flag;
int choice1, item;
char ch;
int main_menu(int *choice1);
int insert(tree **root, int item);
int display(tree *root);
tree *root = NULL;
while (1) {
system("clear");
main_menu(&choice1);//calling function to display original menu list
switch (choice1) {
case 1:
printf("\nEnter number to be inserted:");
scanf("%d", &item);
insert(&root, item);
break;
case 2:
//delete();
break;
case 3:
//search();
break;
case 4:
//printf("\nTerminating code.....");
display(root);
//return(1);
break;
default:
printf("\nInvalid choice!!");
break;
}
getchar();
printf("Enter y to continue");
ch = getchar();
if (ch != 'y')
break;
}
return (1);
}
int main_menu(int *choice1) {
printf("\t\tThe main menu of operations are listed below ");//showing menu
printf("\n1.insert a value.\n2.delete a value.\n3.search a value \n4.display");
printf("\n\nEnter choice:");
scanf("%d", &*choice1);//taking choice of user as input
return (1);
}
tree *getnode(int item) { //function to create node and returning node pointer
tree *p;
p = (tree *)malloc(sizeof(tree));
p->right = NULL;
p->left = NULL;
p->info = item;
return (p);
}
int insert(tree **root, int item) {
tree *ptr, *ptr1, *new;
int flag;
flag = 0;
new = getnode(item);
if (*root == NULL) {
*root = new;
(*root)->left = NULL;
(*root)->right = NULL;
} else {
ptr = *root;
while ((ptr != NULL) && (flag == 0)) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
}
if (ptr->info == item) {
flag = 1;
printf("\nalready present");
return (1);
}
if (item > ptr->info) {
ptr = ptr->right;
}
}
/*if (ptr == NULL) {
new = getnode(item);
}*/
if (ptr1->info < item) {
ptr1->right = new;
} else {
ptr1->left = new;
}
}
return (1);
}
The problem is in the while loop descending the tree: you should add else clauses so the next if test is not evaluated with the updated value of ptr:
while ((ptr != NULL) && (flag == 0)) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
} else
if (ptr->info == item) {
flag = 1;
printf("\nalready present");
return (1);
} else
if (item > ptr->info) {
ptr = ptr->right;
}
}
Note that the flag indicator is redundant as you return directly from the while loop body when you set it to 1.
Note also that the prototypes for the functions called from main should be outside of the body of main so they are visible when the functions are defined and any conflicts can be detected by the compiler.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct tree {
int info;
//char *Name;
struct tree *left;
struct tree *right;
} tree;
int main_menu(int *choice1);
int insert(tree **root, int item);
int display(tree *root);
// read and discard the rest of the input line
// return EOF at end of file
int flush_input(void) {
int ch;
while ((ch = getchar()) != EOF && ch != '\n')
continue;
return ch;
}
int main() {
int flag, choice1, item, ch;
tree *root = NULL;
for (;;) {
system("clear");
main_menu(&choice1); //calling function to display original menu list
switch (choice1) {
case 1:
printf("\nEnter number to be inserted: ");
if (scanf("%d", &item) != 1) {
flush_input();
break;
}
flush_input();
insert(&root, item);
break;
case 2:
//delete();
break;
case 3:
//search();
break;
case 4:
//printf("\nTerminating code.....");
display(root);
//return(1);
break;
default:
printf("\nInvalid choice!!");
break;
}
printf("Enter y to continue: ");
/* read and discard the rest of the input line */
ch = getchar();
flush_input()
if (ch != 'y')
break;
}
return 0;
}
int main_menu(int *choice1) {
printf("\t\tThe main menu of operations are listed below ");//showing menu
printf("\n1.insert a value.\n2.delete a value.\n3.search a value \n4.display");
printf("\n\nEnter choice:");
*choice1 = -1; //default input incase of scanf failure
scanf("%d", choice1); //taking choice of user as input
flush_input(); // discard rest of the line
return 1;
}
tree *getnode(int item) { //function to create node and returning node pointer
tree *p = (tree *)malloc(sizeof(tree));
p->right = NULL;
p->left = NULL;
p->info = item;
return p;
}
int insert(tree **root, int item) {
tree *new, *ptr, *ptr1;
ptr1 = ptr = *root;
while (ptr != NULL) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
} else
if (item > ptr->info) {
ptr = ptr->right;
} else {
printf("\nalready present\n");
return 1;
}
}
new = getnode(item);
if (ptr1 == NULL) {
*root = new;
} else
if (ptr1->info < item) {
ptr1->right = new;
} else {
ptr1->left = new;
}
return 1;
}
I am making a Hash Map with people's names as its key using C language. I am using separate chaining to resolve the collision.
This is my code:
#include<stdio.h>
#include<stdlib.h>
#define MinTableSize 1
#include <stdbool.h>
//Colission resolution Using linked list
struct ListNode;
typedef struct ListNode *Position;
struct HashTbl;
typedef struct HashTbl *HashTable;
typedef unsigned int Index;
Index Hash(const char *Key, int Tablesize)
{
unsigned int HashVal = 0;
while(*Key != '\0')
{
HashVal += *Key++;
}
return HashVal % Tablesize;
}
struct ListNode
{
int Element;
Position Next;
};
typedef Position List;
struct HashTbl
{
int TableSize;
List *TheLists;
};
//Function to find next prime number for the size
bool isPrime(int n)
{
if(n <= 1)
{
return false;
}
if(n <= 3)
{
return true;
}
if(n%2 == 0 || n%3 == 0)
{
return false;
}
for(int i = 5; i*i <= n; i = i + 6)
{
if(n%i == 0 || n%(i + 2) == 0)
{
return false;
}
}
return true;
}
int NextPrime(int N)
{
if(N <= 1)
{
return 2;
}
int prime = N;
bool found = false;
while(!found)
{
prime++;
if(isPrime(prime))
{
found = true;
}
}
return prime;
}
HashTable InitializeTable(int TableSize)
{
HashTable H;
int i;
if(TableSize < MinTableSize)
{
printf("Table size is too small\n");
return NULL;
}
H = malloc(sizeof(struct HashTbl));
if(H == NULL)
{
printf("Out of space\n");
return NULL;
}
H->TableSize = NextPrime(TableSize);
H->TheLists = malloc(sizeof(List) * H->TableSize);
if(H->TheLists == NULL)
{
printf("Out of space\n");
return NULL;
}
for(i = 0; i < H->TableSize; i++)
{
H->TheLists[i] = malloc(sizeof(struct ListNode));
if(H->TheLists[i] == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
H->TheLists[i]->Next = NULL;
}
}
return H;
}
//funtion to find the value
Position Find(const char *Key, HashTable H)
{
Position P;
List L;
L = H->TheLists[Hash(Key, H->TableSize)];
P = L->Next;
while(P != NULL && P->Element != Key)
{
P = P->Next;
}
return P;
}
void Insert(const char *Key, HashTable H)
{
Position Pos;
Position NewCell;
List L;
Pos = Find(Key, H);
if(Pos == NULL)
{
NewCell = malloc(sizeof(struct ListNode));
if(NewCell == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
L = H->TheLists[Hash(Key, H->TableSize)];
NewCell->Next;
NewCell->Element = Key;
L->Next = NewCell;
printf("Key inserted\n");
}
}
else
{
printf("Key already exist\n");
}
}
int main()
{
char Name[6][20] = {"Joshua", "Erica", "Elizabeth", "Monica", "Jefferson", "Andrian"};
int Size = sizeof(Name[0])/sizeof(Name[0][0]);
HashTable H = InitializeTable(Size);
Insert(Name[0], H);
Insert(Name[1], H);
Insert(Name[2], H);
Insert(Name[3], H);
}
The putout of this code is:
Key inserted
Key inserted
This means, it only successfully inserted two keys, while the other name has not been inserted. I think there's some error in my Insert() function, but I got no clue. I tried using an online compiler and it compile properly.
I am working on building circular doubly linked list code.
In my code, there are four function- add node, delete node, print clockwise, print counterclockwise. All my code works fine, besides the delete function. The if(recycle->name == x) line seems not working properly, and free(recycle) also doesn't successfully free the recycle node.
My original code are. as follows
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define nameLen 20
struct Node
{
char name[nameLen];
struct Node *left; //next
struct Node *right; //previous
};
struct Node* current;
struct Node* head;
int count = 0;
struct Node* GetNewNode(char *x)
{
struct Node* newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
strncpy(newNode->name, x, nameLen);
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
void add_name(char *x)
{
struct Node* temp = current;
struct Node* newNode = GetNewNode(x);
count++;
if(current == NULL)
{
current = newNode;
head = current;
}
else
{
current->left = newNode;
newNode->right = temp;
current = newNode;
current->left = head;
head->right = current;
}
printf("Add %s into database.\n\n", current->name);
}
void delete_name(char *x)
{
int i, j;
struct Node* recycle = current;
if(current == NULL)
{
printf("No data input.");
}
else
{
for (i = 0; i < count; i++)
{
if(recycle->name == x)
{
free(recycle);
j++;
printf("Delete %s from database.\n", x);
}
recycle = recycle->left;
}
if(j == 0)
{
printf("There is no %s in data", x);
}
current = recycle;
}
}
void print_clock(int number)
{
int i;
struct Node* temp = current;
if(temp == NULL)
{
printf("No data input.");
}
else
{
printf("Clockwise: \n");
for(i = 0; i < number; i++)
{
printf("%s ",temp->name);
temp = temp->left;
}
}
printf("\n\n");
}
void print_counter(int number)
{
int i;
struct Node* temp = current;
if(temp == NULL)
{
printf("No data input.");
}
else
{
printf("Counterclockwise: \n");
for(i = 0; i < number; i++)
{
printf("%s ",temp->name);
temp = temp->right;
}
}
printf("\n\n");
}
int main()
{
char s1;
char s2[nameLen];
char name[nameLen];
int number;
while(1)
{
printf("Enter the instruction: ");
scanf("%s %s", &s1, s2);
if (s1 == '+' && sscanf(s2, "%d", &number) == 1)
{
printf("Print out %d name(s) clockwise.\n", number);
print_clock(number);
}
else if (s1 == '-' && sscanf(s2, "%d", &number) == 1)
{
printf("Print out %d name(s) counterclockwise.\n", number);
print_counter(number);
}
else if (s1 == '+' && sscanf(s2, "%s", name) == 1)
{
add_name(s2);
}
else if (s1 == '-' && sscanf(s2, "%s", name) == 1)
{
delete_name(s2);
}
else if (s1 == 'e')
{
printf("Bye.\n");
break;
}
else // No match.
printf("Wrong Input. %s %s\n", &s1, s2);
}
system("pause");
return 0;
}
Statement recycle->name == x checks if two pointers point to the same object in memory. It does not check if two (different) objects in memory have equal content.
Use
if (strcmp(recycle->name, x) == 0) { ...
to check for equal string contents.
I'm having a problem when using linked list to build a queue program. Here's the full code.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define ERROR_VALUE -300000
typedef struct LinkedNode {
int data;
struct LinkdedNode* link;
}Node;
Node* front;
Node* rear;
void init_queue() { front = rear = NULL; }
int is_empty() { return (front = NULL && rear == NULL); }
int size() {
Node* p;
int count = 0;
if (is_empty())
return 0;
for (p = front; p != rear; p = p->link) {
count++;
return count + 1;
}
}
void enqueue(int e) {
Node* p = (Node*)malloc(sizeof(Node));
p->data = e;
p->link = NULL;
if (is_empty())
front = rear = p;
else {
rear->link = p;
rear = p;
}
}
int dequeue() {
Node* p = front;
int e;
if (is_empty()) {
printf("Queue Empty Error!\n");
return ERROR_VALUE;
}
else if (size() == 1) {
front = rear = NULL;
}
else
front = p->link;
e = p->data;
free(p);
return e;
}
int peek() {
if (is_empty()) {
printf("Queue Empty Error!\n");
return ERROR_VALUE;
}
return front->data;
}
void print_queue() {
Node* p;
printf("QUEUE STATUS: size=%d\n", size());
if (is_empty())
return;
for (p = front; p != NULL; p = p->link)
printf("[%2d] ", p->data);
printf("\n");
}
int main(void) {
int val, sel;
init_queue();
while (1) {
do {
printf("1.ENQUEUE 2.DEQUEUE 3.PEEK 4.STATUS 0.EXIT :");
scanf("%d", &sel);
} while (sel < 0 || sel > 4);
if (sel == 1) {
printf("1.ENQUEUE VALUE ? ");
scanf("%d", &val);
enqueue(val);
}
else if (sel == 2) {
val = dequeue();
if (val != ERROR_VALUE)
printf("2.DEQUEUE VALUE = %d\n", val);
}
else if (sel == 3) {
val = peek();
if (val != ERROR_VALUE)
printf("3.PEEK VALUE = %d\n", val);
}
else if (sel == 4)
print_queue();
else if (sel == 0) break;
}
return 0;
}
I didn't made is_full() function because linked list is "dynamic". When debugging, the program stops when I try enqueuing value. My guess is that there is something wrong in enqueue function, but cannot find what.
This is wrong:
int is_empty() { return (front = NULL && rear == NULL); }
Note the front = NULL. That means every time you call is_empty(), front gets set to NULL, which then causes is_empty() to return 0 because front = NULL evaluates to NULL.
You need to change is_empty() to
int is_empty() { return (front == NULL && rear == NULL); }
And this is exactly why many programmers use "Yoda conditions" like NULL == front - they prevent this type of bug because if you write = instead of == the code will fail to compile.
And, as you've noticed, such bugs are very hard to spot in your own code.
I'm trying to create a program that makes a bfs in graphs. I have created the adjacency matrix and the bfs function. The program works if I enter a small input (like 4 nodes), but if I enter bigger inputs I start getting segmentation fault.
Thing is, I don't get it always in the same place. Everytime I run it, it may crash on a different iteration, but certainly in the same loop. Here is my code:(I'm just posting the functions that I think are relevant to the problem, but if you think you need more code, just ask).
void matrixBfs(int n, int matrix[n][n], Node nodeLocker[n], int source)
{
int aux;
Box* head =(Box*) malloc(sizeof(Box*));
if (head == NULL)
{
printf("Memory failure\n");
}
head->next = NULL;
add(head, source);
nodeLocker[source].checked = 1;
while (len(head) > 0)
{
aux = pop(head);
for(int i=0; i<n; i++)
{
if ((matrix[aux][i]) && !(nodeLocker[i].checked))
{
add(head, i);
nodeLocker[i].checked = 1;
}
}
}
head = NULL;
free(head);
}
This is the function that crashes, and by printing I have determined that crashes either on the
while (len(head) > 0)
and the
add(head, i);
statements.
Those functions are:
// Returns the length of the list.
int len(Box* head)
{
int i = 0;
Box* current = head;
for(i; current->next != NULL; i++)
{
current = current-> next;
}
return i;
}
// Adds an element at the end of the list
void add(Box* head, int value)
{
Box* current = head;
while((current->next) != NULL)
{
current = (current->next);
}
Box* auxNode = (Box*) malloc(sizeof(Box*));
if (auxNode == NULL)
{
printf("Memory failure\n");
}
auxNode->id = value;
auxNode->next = NULL;
current->next = auxNode;
}
Again, by printing, I have determined that both of them crash when checking the next node of the linked list. That is, in
for(i; current->next != NULL; i++)
and
while((current->next) != NULL)
I'm sorry for the extension of my question, and would greatly appreciate any help on this matter. So thanks in advance.
EDIT: Here is the entire code in case is needed:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Lists.c"
typedef struct Nodo
{
int id; // Representative value
int checked; // 0 if the node wasn't visited; and 1 if it was.
} Node;
void initializeLocker(int n, Node nodeLocker[n])
{
for (int i=0; i < n; i++)
{
nodeLocker[i].id = i;
nodeLocker[i].checked = 0;
}
}
void matrixBfs(int n, int matrix[n][n], Node nodeLocker[n], int source)
{
int aux;
Box* head =(Box*) malloc(sizeof(Box*));
if (head == NULL)
{
printf("Memory failure\n");
}
head->next = NULL;
add(head, source);
nodeLocker[source].checked = 1;
while (len(head) > 0)
{
aux = pop(head);
for(int i=0; i<n; i++)
{
if ((matrix[aux][i]) && !(nodeLocker[i].checked))
{
add(head, i);
nodeLocker[i].checked = 1;
}
}
}
head = NULL;
free(head);
}
int main()
{
FILE* file = fopen("Input.in","r");
char c[5];
char* pch;
int n;
int num;
int num2;
fgets(c, 5, file);
n = atoi(c); // Number of nodes.
if (n < 0)
{
printf("Must input at least one node");
exit(1);
}
int matrix[n][n];
// Initialization loop
for (int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
matrix[i][j] = 0;
}
}
// Insertion loop.
while(fgets(c, 5, file))
{
pch = strtok(c, " ");
num = atoi(pch) - 1;
pch = strtok(NULL, " ");
num2 = atoi(pch) - 1;
matrix[num][num2] = 1;
matrix[num2][num] = 1;
}
fclose(file); // No further use of the file.
pch = NULL;
free(pch);
Node nodeLocker[n];
initializeLocker(n, nodeLocker);
matrixBfs(n, matrix, nodeLocker, 0);
for (int i=0; i<n; i++)
{
if(nodeLocker[i].checked == 0)
{
printf("The entered graph has at least 1 node aislated. Please enter
a new graph.");
exit(1);
}
}
initializeLocker(n, nodeLocker);
nodeLocker[0].checked = 1;
matrixBfs(n, matrix, nodeLocker, 1);
for (int i=1; i<n; i++)
{
if (nodeLocker[i].checked == 0)
{
printf("%d is a linker agent.\n", 1);
break;
}
}
for (int i=1; i<n; i++)
{
initializeLocker(n, nodeLocker);
nodeLocker[i].checked = 1;
matrixBfs(n, matrix, nodeLocker, 0);
for (int j=0; j<n; j++)
{
if (nodeLocker[j].checked == 0)
{
printf("%d is a linker agent.\n", i+1);
break;
}
}
}
return 0;
}
The "Box" structure is defined in this file:
#include <stdio.h>
#include <stdlib.h>
typedef struct Box
{
int id;
struct Box* next;
} Box;
// Adds an element at the end of the list.
void add(Box* head, int value)
{
Box* current = head;
Box* next = NULL;
if (current != NULL)
{
next = current->next;
}
while(next != NULL)
{
current = next;
next = current->next;
}
Box* auxNode = (Box*) malloc(sizeof(Box*));
if (auxNode == NULL)
{
printf("Memory failure\n");
}
auxNode->id = value;
auxNode->next = NULL;
current->next = auxNode;
}
// Returns the length of the list
int len(Box* head)
{
int i = 0;
Box* current = head;
Box* next = NULL;
if (current != NULL)
{
next = current->next;
}
for(i; next != NULL; i++)
{
current = next;
next = current-> next;
}
return i;
}
// Prints the entire list
void printLine(Box* head)
{
if (head->next == NULL)
{
printf("The list is empty\n");
return;
}
Box* current = head;
current = current->next;
printf("[%d", (current->id) + 1);
while (current->next != NULL)
{
current = current->next;
printf(", %d", (current->id) + 1);
}
printf("]\n");
}
// Deletes and returns the last element of the list
int pop(Box* head)
{
Box* auxNode;
int value;
if (len(head) == 1)
{
auxNode = head->next;
head->next = NULL;
value = auxNode->id;
auxNode = NULL;
free(auxNode);
return value;
}
Box* current = head;
while (current->next->next != NULL)
{
current = current->next;
}
auxNode = current->next;
value = current->next->id;
current->next = NULL;
auxNode = NULL;
free(auxNode);
return value;
}
Finally, the input is entered using the "Input.txt" file. Here, the first line shows the number of nodes of the graph, and the rest shows the connections between them:
9
1 2
1 3
1 5
2 3
2 5
3 5
4 7
5 6
5 7
5 9
6 7
6 9
7 8
7 9
8 9
In both the statements causing segmentation fault, you are not checking if current is NULL. Instead use something like this in both len and add functions:
int len(Box* head)
{
int i = 0;
Box* current = head;
Box* next = NULL;
if (current != NULL) {
next = current->next;
}
for(i; next != NULL; i++)
{
current = next;
next = current-> next;
}
return i;
}
// Adds an element at the end of the list
void add(Box* head, int value)
{
Box* current = head;
Box* next = NULL;
if (current != NULL) {
next = current->next;
}
while(next != NULL)
{
current = next;
next = current->next;
}
Box* auxNode = (Box*) malloc(sizeof(Box*));
if (auxNode == NULL)
{
printf("Memory failure\n");
}
auxNode->id = value;
auxNode->next = NULL;
current->next = auxNode;
}