Linked list append doesn't work the last time - c

Why does the last append call not work? I have to add some garbage here because it is complaining that my post is mostly code, I hope it is enough details by now.
typedef struct node {
int val;
struct node * next;
} node_t;
void append_node(node_t * head, int val) {
node_t * current = head;
while(current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof(node_t));
if(current->next == NULL)
printf("err");
current = current->next;
current->val = val;
current->next = NULL; //malloc(sizeof(node_t));
}
void print_list(node_t * head) {
node_t * current = head;
while(current->next != NULL) {
printf("%d ", current->val);
current = current->next;
}
printf("\n");
}
int main() {
node_t * list = malloc(sizeof(node_t));
list->val = 1;
list->next = NULL;
append_node(list,12);
append_node(list,14);
append_node(list,17);
print_list(list);
return 0;
}
Output:
1 12 14

The problem is in your print function. You don't print the last element.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node * next;
} node_t;
void append_node(node_t * head, int val) {
node_t * current = head;
while(current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof(node_t));
if(current->next == NULL)
printf("err");
current = current->next;
current->val = val;
current->next = NULL; //malloc(sizeof(node_t));
}
void print_list(node_t * head) {
node_t * current = head;
while(current!= NULL) {
printf("%d ", current->val);
current = current->next;
}
printf("\n");
}
int main() {
node_t * list = malloc(sizeof(node_t));
list->val = 1;
list->next = NULL;
append_node(list,12);
append_node(list,14);
append_node(list,17);
print_list(list);
return 0;
}

Related

Find item in a Linked List in C

Following the tutorial, I wrote down this function to find the key in a linked list. However, it doesn't seem to work for me, curious about the reason. Here's part of the find function:
node_t *find_node(node_t *head, int number_to_find)
{
node_t *tmp = head;
while (tmp != NULL)
{
if(tmp->value == number_to_find)
{
return tmp;
tmp = tmp->next;
}
}
return NULL;
}
I embedded this function into my program. It successfully compiled but as it runs, the terminal did not show anything.
#define MAX_LIST 25
typedef struct node
{
int value;
struct node *next;
}node_t;
node_t *create_new_node(int value)
{
node_t *new = malloc(sizeof(node_t));
new->value = value;
new->next = NULL;
return new;
}
node_t *add_to_list(node_t *head, node_t *next_node)
{
next_node->next = head;
return next_node;
}
/*
TO FIND VALUE IN THE LINKED LIST
*/
node_t *find_link_list(node_t *head, int number_to_find)
{
node_t *tmp = head;
while (tmp != NULL)
{
if(tmp->value == number_to_find)
{
return tmp;
tmp = tmp->next;
}
}
return NULL;
}
bool print_linked_list(node_t *head)
{
if(head == NULL)
{
return false;
}
else
{
node_t *tmp = head;
while(tmp != NULL)
{
printf("%d ", tmp->value);
tmp = tmp->next;
}
return true;
}
}
int main()
{
node_t *head = NULL;
node_t *tmp;
for(int i = 0; i < MAX_LIST; i++)
{
tmp = create_new_node(i);
head = add_to_list(head, tmp);
}
tmp = find_link_list(head, 9);
printf("%d \n", tmp->value);
print_linked_list(head);
}
Anyone has a clue why this happen? It would be much appreciated : )
tmp = tmp->next;
should be outside of the if statement. Currently, you're saying, get to the next node in the list only if the value is equal to the target value. So instead you can have
while (tmp != NULL)
{
if(tmp->value == number_to_find)
{
return tmp;
}
tmp = tmp->next;
}

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

linked list c programming error by inserting new element

I am trying to insert an element but it get the error "Process finished with exit code 11"
struct node {
int key;
struct node *next;
};
struct node* init(){
struct node *head =NULL;
return head;
}
void create(struct node * head,int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while(tmp!= NULL && tmp->key < num){
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp== NULL)
head=tmp;
}
int main() {
int num;
struct node* head;
head=init()
printf("Enter data:");
scanf("%d",&num);
create(head,num);
}
i am trying to insert an element into a linked list and the element should be sorted and entered at the same time.can someone tell me that the error is ? i cannot seem to find out the error.
It's not clear what your function create()
void create(struct node * head, int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while (tmp != NULL && tmp->key < num) {
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp == NULL)
head = tmp;
}
is supposed to do. You effectively pass it a NULL pointer and return void, so everything it does is meaningless to the outside world.
Thetm starting point for every no bs linked list implementation:
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct node_tag {
int value;
struct node_tag *next;
} node_t;
// write functions to encapsulate the data and provide a stable interface:
node_t* node_create_value(int value)
{
node_t *new_node = calloc(1, sizeof *new_node);
if(new_node) new_node->value = value;
return new_node;
}
node_t* node_advance(node_t const *node) { return node->next; }
typedef struct list_tag { // a list usually consists of
node_t *head; // a pointer to the first and
node_t *tail; // a pointer to the last element
// size_t size; // one might want to add that.
} list_t;
list_t list_create(void)
{
list_t list = { NULL, NULL };
return list;
}
// make code based on these functions "speak" for itself:
node_t* list_begin(list_t const *list) { return list->head; }
node_t* list_end (list_t const *list) { return list->tail; }
bool list_is_empty(list_t const *list) { return !list_begin(list); }
// common operations for lists:
node_t* list_push_front(list_t *list, int value)
{
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = list->head;
return list->head = new_node;
}
node_t* list_push_back(list_t *list, int value)
{
// push_back on an empty list is push_front:
if (list_is_empty(list))
return list->tail = list_push_front(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
list->tail->next = new_node;
return list->tail = new_node;
}
node_t* list_insert_after(list_t *list, node_t *node, int value)
{
if (list_end(list) == node)
return list_push_back(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = node->next;
return node->next = new_node;
}
node_t* list_insert_sorted(list_t *list, int value)
{
// first handle the special cases that don't require iterating the whole list:
if (list_is_empty(list) || value < list_begin(list)->value)
return list_push_front(list, value);
if (value > list_end(list)->value)
return list_push_back(list, value);
// the general (worst) case:
for (node_t *current_node = list_begin(list); node_advance(current_node); current_node = node_advance(current_node))
if (value < node_advance(current_node)->value)
return list_insert_after(list, current_node, value);
return NULL; // should never happen
}
void list_print(list_t const *list)
{
for (node_t *current_node = list_begin(list); current_node; current_node = node_advance(current_node))
printf("%d\n", current_node->value);
}
void list_free(list_t *list)
{
for(node_t *current_node = list_begin(list), *next_node; current_node; current_node = next_node) {
next_node = current_node->next;
free(current_node);
}
}
// user code should not be required to know anything about the inner workings
// of our list:
int main(void)
{
list_t list = list_create();
for (int i = 1; i < 10; i += 2) {
if (!list_push_back(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
putchar('\n');
for (int i = 0; i < 11; i += 2) {
if (!list_insert_sorted(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
list_free(&list);
}
Output:
1
3
5
7
9
0
1
2
3
4
5
6
7
8
9
10

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.

Resources