Add function in a trie structure does not work properly - c

I'm trying to write a function to add words in a trie, and count the number of times it has been added. But it always returns 1.
Can anybody help me?
struct node
{
struct node* next;
struct node* child;
char data;
int value;
};
typedef struct node Node;
Node* getNode(char data)
{
Node* newptr;
newptr = calloc(1,sizeof(Node));
newptr->next = NULL;
newptr -> child = NULL;
newptr->data = data;
newptr -> value = 0;
return newptr;
}
Node* add(Node* parent,char* str)
{
Node* current;
current = parent->child;
while (current != NULL && current->data != str[0])
{
current = current->next;
}
if (current == NULL)
{
current = getNode(str[0]);
if (str[0] == 0)
{
current->value = 1;
return current;
}
return add(current,str + 1);
}
if (str[0] == 0)
{
(current->value)++;
return current;
}
return add(current,str+1);
}
cm: getNode() and Node definitions added!

Related

Multiple data inside a single linked list node

Is it possible to have multiple data inside a single linked list node in C? And how do you input and access data with this?
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
char name[30];
struct node *next;
};
struct node *head, *tail = NULL;
void addNode(int data, char string) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = data;
newNode->name[30] = string;
newNode->next = NULL;
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void sortList() {
struct node *current = head, *index = NULL;
int temp;
if(head == NULL) {
return;
}
else {
while(current != NULL) {
index = current->next;
while(index != NULL) {
if(current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
struct node *current = head;
if(head == NULL) {
printf("List is empty \n");
return;
}
while(current != NULL) {
printf("%d - %s", current->data, current->name);
current = current->next;
}
printf("\n");
}
int main()
{
char string1[10] = "Aaron";
char string2[10] = "Baron";
char string3[10] = "Carla";
addNode(9, string1);
addNode(7, string2);
addNode(2, string3);
printf("Original list: \n");
display();
sortList();
printf("Sorted list: \n");
display();
return 0;
}
I don't understand why my code didn't work. I was trying to make use of single linked list where it can accept/input and print/output the number and the name at the same time.
What I want it to happen is to print the number and the name.
The output should be:
Carla - 2
Baron - 7
Aaron - 9
Please read my comments marked as // CHANGE HERE.
// CHANGE HERE: accept a character array as argument
void addNode(int data, char string[]) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = data;
// CHANGE HERE: copy char array argument to name
strncpy(newNode->name, string, 30);
newNode->next = NULL;
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void sortList() {
struct node *current = head, *index = NULL;
int temp;
char temp1[30];
if(head == NULL) {
return;
}
else {
while(current != NULL) {
index = current->next;
while(index != NULL) {
if(current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
// CHANGE HERE: swap the name along with data
strncpy(temp1, current->name, 30);
strncpy(current->name, index->name, 30);
strncpy(index->name, temp1, 30);
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
struct node *current = head;
if(head == NULL) {
printf("List is empty \n");
return;
}
while(current != NULL) {
printf("%d - %s\n", current->data, current->name);
current = current->next;
}
printf("\n");
}

Circular doubly linked list in C delete function

I have a circular doubly linked list.
The deletefront() function is not working: the output is wrong. What is the mistake?
The other functions are working. But I get a wrong output after displaying after calling deletefront function. The 100 value which should be deleted is still appearing. Please correct it.
I have included the C source code:
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *rlink;
struct node *llink;
} node;
node *head = NULL;
node *getnode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
void insertfront(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
head->llink = newnode;
newnode->rlink = head;
head = newnode;
}
}
void insertend(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
node *temp = head;
do {
temp = temp->rlink;
} while (temp != head->llink);
newnode->rlink = temp->rlink;
temp->rlink = newnode;
newnode->llink = temp;
}
}
int lenlist() {
node *temp;
int count = 0;
temp = head;
do {
temp = temp->rlink;
count++;
} while (temp != head);
return count;
}
void insertatpos(int ele,int pos) {
if (pos == 1) {
insertfront(ele);
} else
if (pos == (lenlist() + 1)) {
insertend(ele);
} else
if (pos > 1 && pos <= (lenlist() + 1)) {
node *prev, *curr;
node *newnode = getnode(ele);
int count = 1;
curr = head;//curr points to 1st node
do {
prev = curr;
count++;
curr = curr->rlink;
if (count == pos) {
prev->rlink = newnode;
newnode->llink = prev;
newnode->rlink = curr;
curr->llink = newnode;
}
} while (curr != head);
} else {
printf("invalid position");
}
}
void delfront() {
if (head == NULL)
printf("empty list");
node *aux;
node *lastnode, *secondnode;
aux = head;
lastnode = head->llink;
secondnode = head->rlink;
secondnode->llink = lastnode;
lastnode->rlink = secondnode;
free(aux);
head = secondnode;
}
void display() {
node *aux = head;
do {
printf("%d->", aux->data);
aux = aux->rlink;
} while (aux != head);
printf("\n");
}
int main() {
insertfront(100);
insertend(20);
printf("\n%d\n", lenlist());
insertatpos(45, 2);
display();
delfront();
display();
}
The problem is not in the deletefront() function, instead, you have missed updating a few links in the insertfront() and insertend() functions.
I have updated the code here and also added the comment where I made the changes. Try to visualise it using an example.
However, I suggest that you solve such issues using a debugger or go through the code with a sample test case. It will improve you debugging as well as coding skills!
Your code have a lot of mistakes.
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
/*i changed the names of your pointers here*/
typedef struct node {
int data;
struct node *prev, *next;
} node;
/*
node *head = NULL;
This will be removed.
Avoid using globals as much as you can.
*/
/*
This function is unecessary.
node *createNode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
*/
char insertFront(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
}
*head=newNode;
return 1;
}
char insertEnd(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
*head=newNode;
}
return 1;
}
/*You could simple create a struct list that would have as members
the head of your list and its height to avoid calculating it each time
you want it but anyway. I will fix that.
int lenList(node *head) {
if (*head==NULL) return 0;
node *temp=head;
int count = 0;
do {
temp = temp->next;
count++;
} while (temp != head);
return count;
}
*/
char insertNatP(node **head, int ele, int pos) {
If (pos<1 || pos>lenList(head)){
printf("Invalid Position\n");
return 0;
}
int i;
for(i=0; i<pos-1; head=&head->next, i++);
node *newNode=malloc(sizeof(node));
If (newNode==NULL){
printf("Memory could not be allocated\n");
return 0;
}
newNode->data=ele;
If (*head!=NULL){
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode
newNode->next=*head;
} else {
newNode->prev=newNode;
newNode->next=newNode;
}
*head=newNode;
return 1;
}
char delFront(node **head) {
if (*head == NULL) return 0;
node garbage=*head;
*head=(*head)->next;
if (*head==garbage) *head=NULL; else{
(*head)->prev=garbage->prev;
garbage->prev->next=*head;
}
free(garbage);
return 1;
}
void printList(node *list) {
if (list==NULL) return;
node *sentinel=list->prev;
while (list!=sentinel) {
printf("%d->", list->data);
list=list->next;
}
printf("%d\n", list->data);
}
int main() {
node *l1=NULL;
insertFront(&l1, 100);
insertEnd(&l1, 20);
printf("\n%d\n", lenList(l1));
insertNatP(&l1, 45, 2);
printList(l1);
delFront(&l1);
printList(l1);
}
Try this

Segmentation Fault Binary Tree Traversal

So i've been running and testing my code and everything seemed to have been working until i added 2 more functions for Pre-order and Post-order traversals of my tree.
The assignment was to create a linked list and tree for an input file with a random set of numbers. The linked list and tree traversals all need to be printed out in separate functions and i can't find where i went wrong.
i keep getting
Segmentation Fault (core dumped)
Here is my code:
//Tristan Shepherd
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct node
{
int num;
struct node *next;
};
struct tree
{
int numt;
struct tree *left;
struct tree *right;
};
typedef struct node LINK;
typedef struct tree branch;
int searchList(int number, LINK *head)
{
LINK *current;
current = head;
while (current != NULL)
{
if (current->num == number)
return 1; // Found it.
current = current->next;
}
return 0; // Did not find it.
}
LINK *insertList(int number, LINK *head)
{
LINK *current, *temp;
if (searchList(number, head) == 1) return head;
temp = (LINK *)malloc(sizeof(LINK));
temp->num = number;
if (head == NULL)
{
head = temp;
temp->next = NULL;
return head;
}
current = head;
if (current->num == number)
{
temp->next = current;
head = temp;
return head;
}
current = head;
while (current != NULL)
{
if (current->next == NULL || current->next->num == number)
{
temp->next = current->next;
current->next = temp;
return head;
}
current = current->next;
}
}
void printList(LINK *head)
{
LINK *current;
current = head;
while (current != NULL)
{
printf("%i\n", current->num);
current = current->next;
}
}
LINK *freeList(LINK *head)
{
LINK *current, *temp;
current = head;
while (current != NULL)
{
temp = current;
current = current->next;
free(temp);
}
free(head);
head = NULL;
return head;
}
void freeTree(branch *leaf)
{
if(leaf != 0)
{
freeTree(leaf->left);
freeTree(leaf->right);
free(leaf);
}
}
void insert(int new, branch **leaf)
{
if(*leaf == 0)
{
*leaf = (struct tree*) malloc(sizeof(struct tree));
(*leaf)->numt = new;
(*leaf)->left = 0;
(*leaf)->right = 0;
}
else if(new < (*leaf)->numt)
{
insert(new, &(*leaf)->left);
}
else if(new > (*leaf)->numt)
{
insert(new, &(*leaf)->right);
}
}
void printInorder(branch *leaf)
{
if (leaf == NULL)
return;
printInorder(leaf->left);
printf("%i ", leaf->numt);
printInorder(leaf->right);
}
void printPreorder(branch *leaf)
{
if (leaf == NULL)
return;
printf("%i ", leaf->numt);
printInorder(leaf->left);
printInorder(leaf->right);
}
void printPostorder(branch *leaf)
{
if (leaf == NULL)
return;
printInorder(leaf->left);
printInorder(leaf->right);
printf("%i ", leaf->numt);
}
int main (void)
{
int t;
FILE *stream = fopen("hw9.data", "r");
LINK *head;
branch *leaf;
head = NULL;
int number;
while (1)
{
fscanf(stream, "%i", &number);
if (feof(stream)) break;
insert(number, &leaf);
head = insertList(number, head);
}
fclose(stream);
printf("\nPrinting List: \n");
printList(head);
printf("\n\nPrinting in order\n");
printInorder(leaf);
printf("\n\nPrinting Pre order\n");
printPreorder(leaf);
printf("\n\nPrinting Post order\n");
printPostorder(leaf);
head = freeList(head);
freeTree(leaf);
head = NULL;
return 0;
}
branch *leaf; is not initialized. Your code expects leaf pointers to be NULL. Try branch *leaf = NULL;
Also, it looks like freeList frees head twice which is undefined behavior.

Inserting a node in ascending order

I try to insert a node that contains a string to the linkedlist in ascending order. It works if the initial of first element is higher than other initials of strings. For example,
"Zeynep"
"Ceylan"
"Demir"
this way works fine.
However if the initial of first string is smaller than any initial of strings in the list, it prints nothing.
"Ali"
"Zeynep"
"Ceylan"
This corrupts.
I traced the code but couldnt find.
struct friendNode
{
char firstName[30];
char lastName[30];
char gender[1];
char birthYear[10];
struct friendNode *next;
};
struct friendRecord
{
struct friendNode *head;
struct friendNode *tail;
int size;
};
void insertFriend(struct friendNode *node, struct friendRecord *list)
{
struct friendNode *temp_node;
temp_node = list->head;
if(temp_node->next == NULL)
{
temp_node->next = node;
list->tail = node;
}
else
{
while(strcmp(node->firstName, temp_node->next->firstName) >= 0 )
temp_node = temp_node->next;
if(temp_node->next == NULL)
{
temp_node->next = node;
list->tail = node;
return;
}
node->next = temp_node->next;
temp_node->next = node;
}
}
Inserting into a linked list is pretty basic stuff. Here is one way to do it:
void insertFriend(struct friendNode *node, struct friendRecord *list)
{
struct friendNode *pre = NULL;
struct friendNode *post = list->head;
while (post && strcmp(node->firstName, post->firstName) >= 0)
{
pre = post;
post = post->next;
}
if (pre == NULL)
{
list->head = node;
}
else
{
pre->next = node;
}
node->next = post;
if (post == NULL)
{
list->tail = node;
}
}
void insertFriend(struct friendNode *node, struct friendRecord *list)
{
struct friendNode *temp_node;
temp_node = list->head;
if(strcmp(node->firstName, list->head->firstName) < 0)
{
node->next = list->head;
list->head = node;
}
if(temp_node->next == NULL)
{
temp_node->next = node;
list->tail = node;
}
else
{
while(strcmp(node->firstName, temp_node->next->firstName) >= 0 )
temp_node = temp_node->next;
if(temp_node->next == NULL)
{
temp_node->next = node;
list->tail = node;
return;
}
node->next = temp_node->next;
temp_node->next = node;
}
}
you forgot to write code to append the node at the head of list if it is going to be the first element. I have not tried because i dont have full code. try out. if still doesn't work, i request to comment.

Doubly linked list - segfault

I have a doubly linked list,
struct node
{
int data;
struct node *prev;
struct node *next;
};
and a deleteEnd function I implemented,
bool deleteEnd(struct node **head, int* value) {
if (*head == NULL) return false;
struct node* end = *head;
while (end->next != NULL) {
end = end->next;
}
if (end == *head) *head = NULL;
else end->prev->next = NULL;
*value = end->data;
free(end);
return true;
}
that gives me a segmentation fault but I can't figure out why. At this point my list have 3 elements (1<->2<->5) and 5 should be deleted.
list.h
#pragma once
#include <stdbool.h>
/* doubly linked list structure */
struct node
{
int data;
struct node *prev;
struct node *next;
};
struct node* create(int value);
bool insertAtBeginning(struct node **head, int value);
bool insertAtEnd(struct node **head, int value);
bool insertAfter(struct node **head, int value, int preVal);
bool deleteBeginning(struct node **head, int* value);
bool deleteEnd(struct node **head, int* value);
bool deleteSpecific(struct node **head, int value);
void display(struct node *head);
list.c
#include "list.h"
#include <stdlib.h>
#include <stdio.h>
struct node* create(int value) {
struct node* n = malloc(sizeof(struct node));
if (n == NULL) return NULL;
n->data = value;
n->prev = NULL;
n->next = NULL;
return n;
}
bool insertAtBeginning(struct node **head, int value) {
struct node* old_head = *head;
*head = create(value);
if (*head == NULL) return false;
(*head)->next = old_head;
return true;
}
bool insertAtEnd(struct node **head, int value) {
// Get last node
struct node* last = *head;
while (last->next != NULL) {
last = last->next;
}
// Insert after
last->next = create(value);
if (last->next == NULL) return false;
else return true;
}
bool insertAfter(struct node **head, int value, int preVal) {
// Get previous
struct node* prev = *head;
while (prev->data != preVal && prev->next != NULL) {
prev = prev->next;
}
// Not founnd ?
if (prev->next == NULL && prev->data != preVal) return false;
// Insert in between
struct node* nxt = prev->next;
struct node* insert = create(value);
if (insert == NULL) return false;
prev->next = insert;
insert->next = nxt;
return true;
}
bool deleteBeginning(struct node **head, int* value) {
struct node* hd = *head;
*value = hd->data;
*head = (*head)->next;
free(hd);
return true;
}
bool deleteEnd(struct node **head, int* value) {
if (*head == NULL) return false;
struct node* end = *head;
while (end->next != NULL) {
end = end->next;
}
if (end == *head) *head = NULL;
else end->prev->next = NULL;
*value = end->data;
free(end);
return true;
}
bool deleteSpecific(struct node **head, int value) {
// Find node
struct node* n = *head;
while (n->data != value && n->next != NULL) {
n = n->next;
}
// Not found ?
if (n->next == NULL && n->data != value) return false;
// Deleting head ?
if (n == *head) {
*head = (*head)->next;
free(n);
}
// Delete in between
else {
struct node* nxt = n->next;
struct node* prev = n->prev;
prev->next = nxt;
free(n);
}
return true;
}
void display(struct node *head) {
if (head == NULL) {
printf("List is Empty!!!");
}
else {
printf("\nList elements are:\n");
do {
printf("%d ", head->data);
head = head->next;
}
while(head != NULL);
printf("\n\n");
}
}
main.c
#include <stdio.h>
#include "list.h"
int main()
{
int value, preVal, retVal;
struct node *head = NULL;
/* insert data */
value = 2;
printf("insert %d %s\n", value, insertAtBeginning(&head, value) ? "OK":"NOK");
display(head);
value = 5;
printf("insert %d %s\n", value, insertAtEnd(&head, value) ? "OK":"NOK");
display(head); // printf("blabla");
value = 3;
printf("insert %d %s\n", value, insertAtBeginning(&head, value) ? "OK":"NOK");
display(head);
value = 3;
preVal = 0;
printf("insert %d after %d %s\n", value, preVal, insertAfter(&head, value, preVal) ? "OK":"NOK");
display(head);
value = 1;
preVal = 3;
printf("insert %d after %d %s\n", value, preVal, insertAfter(&head, value, preVal) ? "OK":"NOK");
display(head);
/* delete data */
retVal = deleteBeginning(&head, &value);
printf("delete %d %s\n", value, retVal ? "OK": "NOK");
display(head);
retVal = deleteEnd(&head, &value);
printf("delete %d %s\n", value, retVal ? "OK": "NOK");
display(head);
value = 3;
retVal = deleteSpecific(&head, value);
printf("delete %d %s\n", value, retVal ? "OK":"NOK");
display(head);
return 0;
}
In case when end is equal to head this statement
end->prev->next = NULL; // <- segfault
results in undefined behavior because end->prev is equal to NULL;
I would define the function the following way
bool deleteEnd(struct node **head, int *value )
{
bool success = *head != NULL;
if ( success )
{
while ( ( *head )->next != NULL ) head = &( *head )->next;
*value = ( *head )->data;
struct node *last = *head;
*head = NULL;
free( last );
}
return success;
}
EDIT: After you showed additional code then it is already seen that at least this function
bool insertAtBeginning(struct node **head, int value) {
struct node* old_head = *head;
*head = create(value);
if (*head == NULL) return false;
(*head)->next = old_head;
return true;
}
is wrong because it does not set the data member prev of old_head.
Or in this function
bool insertAtEnd(struct node **head, int value) {
// Get last node
struct node* last = *head;
while (last->next != NULL) {
last = last->next;
}
// Insert after
last->next = create(value);
if (last->next == NULL) return false;
else return true;
}
there is no check whether *head is equal to NULL. And again the data member prev of the newly created node is not set appropriately.
This that is that the data member prev has the value NULL is the reason of incorrect work of the function deleteEnd.
You should revise all your functions.
You have to check if end element has previous one. If it does not have, you can't write next element to that previous element.
You are missing if statement.
if (end->prev)
end->prev->next = NULL; // <- segfault

Resources