I'm trying to add to my linked list only if the item I'm inserting isn't already in the link list but when I try to traverse it and print out all of the items nothing is printing out. I can't seem to see what I'm doing wrong. Any help would be appreciated
// my add function
void add(char *val)
{
printf("%s", val);// val is getting printed so i know its being passed in.
if(head == NULL){
struct node *new_node = (struct node *)malloc(sizeof(struct node));
head = new_node;
head->item = val;
head->next = NULL;
} else{
struct node *current = head;
struct node *newNode = (struct node *) malloc(sizeof(struct node));
if (newNode == NULL) {
exit(-1);
}
newNode->item = val;
newNode->next = NULL;
while (current != NULL) {
current = current->next;
}
current = newNode;
}
}
//my traverse function
void goThroughList() {
struct node *current = head;
while(current != NULL){
printf("%s\n",current->item);
current= current->next;
}
}
add doesn't successfully add anything once head has been assigned. It only updates a local current pointer. You could fix that by changing the code that searches for the tail of the list to
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
If this doesn't help, can you update your question to show how add is being called? (To rule out the possibility that the same char array is being used for multiple calls, leaving all nodes with their item pointers pointed to the same buffer.
Also, there is no code I can see that checks for duplicates. You could implement this inside the branch of add where head already existed by iterating through the list using strcmp to compare each node's item with val.
your add function is incorrect
try this one :
void add(char *val)
{
printf("%s", val);// val is getting printed so i know its being passed in.
if(head == NULL){
struct node *new_node = (struct node *)malloc(sizeof(struct node));
new_node->item = val;
new_node->next = NULL;
head = new_node;
}
else{
struct node *current = head;
while (current->next != NULL) {
if(strcmp(current->item, val) == 0)
return;
current = current->next;
}
struct node *new_node = (struct node *)malloc(sizeof(struct node));
new_node->item = val;
new_node->next = NULL;
current->next = new_node;
}
}
what list does this function go trought ?
void goThroughList() {
struct node *current = head;
while(current != NULL){
printf("%s\n",current->item);
current= current->next;
}
}
try this instead :
void goThroughList(struct node* llist)
{
if(llist)
{
printf("%s" , llist->item);
goThroughList(llist->next);
}
}
Related
I have been using linked list and I have used the following code for append function which i wrote in a new file and it works perfectly but when I copy it my main code it gives segmentation fault at while(current->next != null) . It does not give any warning while compiling so I don't know whats the issue here.
// Linked List Node for Reading Comments
struct Node{
char value;
struct Node *next;
};
void append(struct Node * headNode, char newElement){
struct Node *newNode = malloc(sizeof(struct Node)); //Dynamically Allocating Memory for New Node
struct Node *current = headNode; //Creating A Node to traverse the linked list
newNode->value = newElement; //Assigning the values of newNode to the given value
newNode->next = NULL; //Setting next value to be null since its the last node
if (headNode == NULL){ //Checking if headnode is empty
headNode = newNode; //Assigning headnode and tailnode to be newnode
}
else {
while(current->next != NULL){ //Traversing through the linked list
current = current->next;
}
current->next = newNode; //Setting tailnode's next to be newnode
}
}
void printLinkedList(struct Node* headNode){
while(headNode != NULL){
fprintf(stderr,"%c",headNode->value);
headNode = headNode->next;
}
}
If anyone can comment on this please do.
Your code does not allow to add a node to an empty list. If you try and did not initialise your head pointer on the calling side, you may get such behavior.
For instance, in main you could have:
struct Node* head; // not initialised
append(head, 'a');
printLinkedList(head);
These are then the issues:
If head happens to be not NULL, then the else block will kick in and the current pointer will reference some unintended memory address.
append will not change the head variable of main. It will only modify a local variable that happens to have a similar name (headNode).
To correct, pass the address of head to the append function, and let append deal with this accordingly:
void append(struct Node ** headNode, char newElement) {
struct Node *newNode = malloc(sizeof(struct Node));
struct Node *current = *headNode;
newNode->value = newElement;
newNode->next = NULL;
if (*headNode == NULL) {
*headNode = newNode;
} else {
while(current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
Note the additional * wherever headNode occurs. In main:
struct Node* head;
append(&head, 'a');
printLinkedList(head);
I am just trying to insert a value to a sorted doubly linked list in C.
When I print it out using the following it never shows the newly created node. I created a new node and then set the values and then update the prev and next pointers for the new node and the node that was in front of it. I am sure it has something to do with pass by reference and would like to understand why?
struct NodeType {
int data;
struct NodeType * prev;
struct NodeType * next;
}*head, *last;
void insert_double(int key);
void displayList();
void find_node(int key);
int main()
{
head = NULL;
last = NULL;
/* Create a list with one as value and set as head */
head = (struct NodeType *)malloc(sizeof(struct NodeType));
head->data = 3;
head->prev = NULL;
head->next = NULL;
last = head;
int value=1;
insert_double(value);
printf("0\n");
displayList();
printf("1\n");
value=2;
printf("2\n");
find_node(value);
printf("3\n");
displayList();
return 0;
}
void displayList()
{
struct NodeType * temp;
int n = 1;
if(head == NULL)
{
printf("List is empty.\n");
}
else
{
temp = head;
printf("DATA IN THE LIST:\n");
while(temp != NULL)
{
printf("DATA of %d node = %d\n", n, temp->data);
n++;
/* Move the current pointer to next node */
temp = temp->next;
}
}
}
void find_node(int key)
{
struct NodeType * temp;
struct NodeType * newnode;
newnode->data=key;
if(head == NULL){
printf("No nodes");
}
else{
temp=head;
while(temp!=NULL)
{
if((temp->data)< key){
newnode->prev=temp->prev;
newnode->next=temp;
temp->prev=newnode;
break;
}
else{
temp=temp->next;
}
}
}
}
void insert_double(int key)
{
struct NodeType * newnode;
if(head == NULL)
{
printf("Empty!\n");
}
else
{
newnode = (struct NodeType *)malloc(sizeof(struct NodeType));
newnode->data = key;
newnode->next = head; // Point to next node which is currently head
newnode->prev = NULL; // Previous node of first node is NULL
/* Link previous address field of head with newnode */
head->prev = newnode;
/* Make the new node as head node */
head = newnode;
}
}
Your code is basically correct. You are just missing two important edge cases when dealing with linked list. First is when you are using find_node to insert some value, but it's gonna be add in the beginning in the list. In this case your newly created node becomes a new head of a list so you have to update a head variable. The second edge case is kind of opposite, it happens when you are inserting the new node to the end of the list. Then it becomes an end of a list so you need to update tail.
Missing those two edge cases happens a lot when first working with the linked lists, so don't worry. I think pretty much everybody who worked with linked list made these mistakes in the beginning of his journey.
Moreover you are using the uninitialized pointer to the NodeType structure in find_node:
struct NodeType * newnode;
it should be:
struct NodeType * newnode = (struct NodeType *)malloc(sizeof(struct NodeType));
Thanks to both of you. Here is the solution I came up based on both of your input:
void insert_sorted_node(int key){
struct NodeType * temp = (struct NodeType *)malloc(sizeof(struct NodeType));
struct NodeType * newnode = (struct NodeType *)malloc(sizeof(struct NodeType));
newnode->data=key;
/* no nodes at all*/
/* insert_sorted_node(value) can't start empty list, need to fix */
if(head == NULL){
printf("head =null");
temp = head;
head->data=key;
head->prev=NULL;
head->next=NULL;
last = head;
}
else{
temp=head;
while(temp!=NULL)
{
printf("\n\ndata = %d\nkey = %d\n", temp->data, key);
/* key is new head
1) check if key < head->data
*/
if(key<head->data)
{
printf("\nnew head\n");
newnode->prev = head->prev;
newnode->next = temp;
temp->prev = newnode;
head = newnode;
break;
}
/* key is tail
if temp->next = NULL
*/
else if(temp->next == NULL)
{
printf("\ntail\n");
newnode->prev = temp;
newnode->next = NULL;
temp->next = newnode;
last = newnode;
break;
}
/* key is middle head
if key > temp->data and key< temp->next->data
*/
else if((key>temp->data)&&(key<temp->next->data))
{
printf("\nmiddle\n");
newnode->prev=temp;
newnode->next=temp->next;
temp->next=newnode;
temp->next->prev=newnode;
break;
}
else{
printf("next\n");
temp=temp->next;
}
}
}
}
Your insertion function works fine, as does displayList.
However, the program has undefined behavior in the find_node function:
void find_node(int key)
{
struct NodeType * temp;
struct NodeType * newnode;
newnode->data=key; //<-- BOOM! (writing to uninitialized pointer)
if(head == NULL){
printf("No nodes");
}
else{
temp=head;
while(temp!=NULL)
{
if((temp->data)< key){
newnode->prev=temp->prev; //<-- BOOM!
newnode->next=temp; //<-- BOOM!
temp->prev=newnode;
break;
}
else{
temp=temp->next;
}
}
}
}
It's not really clear what you're trying to achieve there. If this really is a find function, it should not be attempting to perform operations on nodes or copy any data.
All you really need is something like this:
struct NodeType* find_node(int key)
{
for(struct NodeType* temp = head; temp != NULL; temp = temp->next)
{
if (temp->data == key)
return temp;
}
return NULL;
}
i have a single list non-circular without sentinel and i want to duplicate every node of it. For example, i have 7,5,12,16 and i want to have : 7,7,5,5,12,12,16,16 but i can't create it.Below is my function code for duplicate the nodes(other parts of the program are correct).
int duplicate_list(listT *list_head) {
listT *current, *new_node;
for(current = list_head; current != NULL; current = current->next,counter++) {
new_node = (listT *)malloc(sizeof(listT));
if(new_node == NULL) {
printf("problem in new_node\n");
free(new_node);
exit(-1);
}
new_node->data = current->data;
new_node->next = current;
}
return(1);
}
Can someone help me?
You are not inserting duplicate new_node in the list, you are just creating the new nodes in loop. Consider below example for your reference.
int duplicate_list(listT *list_head) {
listT *current, *new_node;
for(current = list_head; current != NULL; current = current->next,counter++) {
new_node = malloc(sizeof(*new_node));
if(new_node == NULL) {
perror("problem in new_node");
exit(1);
}
new_node->data = current->data;
new_node->next = current->next;
current->next = new_node;
current = new_node;
}
return(1);
}
I have been trying to fix this code since morning but could get it done. So, finally i need some help in figuring out the error. The code compiles with no error but when i run it from terminal i get an error saying "segmetation error: 11"
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
struct Node *next;
};
struct Node *head;
void Insert(int data);
void Print();
int main()
{
head = NULL; //list is empty
Insert(3);
Insert(5);
Insert(2);
Insert(8);
Print();
return 0;
}
void Insert(int data)
{
struct Node *temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
struct Node *temp1 = head;
while(temp1 != NULL)
{
temp1= temp1->next;
}
temp1->next = temp;
}
void Print()
{
struct Node *temp =head;
while(temp != NULL)
{
temp = temp->next;
printf("%d", temp->data);
}
}
You never set head to anything other than NULL.
(Even if you fix the above) temp1 is guaranteed to be NULL by the time you get to temp1->next = temp;.
P.S. I don't think it's such a great practice to call you variables temp, temp1 etc. From those names it is impossible to tell what their supposed function is.
Usually single linked lists have an inserting operation that inserts data at the beginning of the list. Nevertheless your function insert can look the following way
void Insert( int data )
{
struct Node *temp = malloc(sizeof( struct Node ) );
temp->data = data;
temp->next = NULL;
if ( head == NULL )
{
head = temp;
}
else
{
struct Node *current = head;
while ( current->next != NULL ) current = current->next;
current->next = temp;
}
}
It would be better if you check in the function whether the node was allocated.
Function Print also is wrong. It can look like
void Print( void )
{
for ( struct Node *current = head; current != NULL; current = current->next )
{
printf( "%d ", current->data );
}
}
You are writing
while(temp1 != NULL)
Make it like this
while(temp1->next != NULL)
Here, temp1 points to null at the end of loop, and you are trying to add node after null i.e.
null->next =temp;
which must be throwing error.
struct Node *curr;
void Insert(int data){
struct Node *temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next =NULL;
if(head == NULL)
curr = head = temp;
else
curr = curr->next = temp;
}
void Print(){
struct Node *temp =head;
while(temp != NULL){
printf("%d ", temp->data);
temp=temp->next;
}
}
#include<stdio.h>
#include<stdlib.h>
struct node {
int num;
struct node *next;
}*head=NULL, *curr=NULL;
void print(){
curr = head;
while(curr != NULL){
printf("%d\n", curr->num);
curr = curr->next;
}
}
struct node* memAlo(){
return (struct node *)malloc(sizeof(struct node));
}
void addNode(int no){
curr = head;
while(curr != NULL){
curr = curr->next;
}
curr = memAlo();
if(curr == NULL){
printf("\nmemory up\n");
return;
}
else{
curr->num = no;
curr->next = NULL;
printf("%d\n",curr->num);
}
}
void hellop(){
printf("%d", head->num);
}
int main(){
int i;
curr = head;
for(i=1;i<10;i++){
addNode(i);
}
print();
/*head = memAlo();
head->num = 1;
head->next = NULL;
hellop();*/
}
I am sure I have messed up somewhere. The thing is that the head pointer doesn't get the memory allocated by the memAlo() fn() but how to get there? Please help
What I am trying is to create a singly linked list holding numbers from 1 to 9 and to print them using print(). Actually AddNode() is to create single node at the end of the linked list each time the for loop in main() executes.
You set head = NULL at the point where you first defined head. Except in that one place, we never see head on the left-hand side of = anywhere in your program. So of course head is always equal to NULL and never anything else.
You will probably want to insert some code at the start of your addNode function to test whether head == NULL at that point; and if that is true, you will want to assign the result of memAlo() to head instead of curr. You will have to adjust some of the other logic as well.
Your code for allocating a node is wrong. It should create a node, make some space for it, then return it.
struct node *memAlo() {
struct node *nd = malloc(sizeof(*nd));
return nd;
}
This creates a pointer to a node, properly allocates it, then returns it.
Problems I see:
Not dealing with empty list, i.e. when head == NULL.
Creating nodes that are not linked to each other.
curr = memAlo();
allocated memory for a node and returns it to you, but it does not connect the node with anything else.
Try this:
void addNode(int no){
struct node* temp = NULL;
// Deal with an empty list.
if ( head == NULL )
{
head = memAlo();
head->num = no;
head->next = NULL;
}
// Move curr until we reach the last node of the list.
curr = head;
while(curr->next != NULL){
curr = curr->next;
}
temp = memAlo();
if(temp == NULL){
printf("\nmemory up\n");
return;
}
else{
// Link the new node to the previous last node.
temp->num = no;
temp->next = NULL;
printf("%d\n",temp->num);
curr->next = temp;
}
}
It seems that since head is initially NULL, and then you start allocating nodes without saving the address of the first one, you lose the address of the first one, and then can't walk the list from the beginning.
The part you commented out illustrate the problem.
As a side note, there is no free in your program. Remember to always free the memory you alloc
#include<stdio.h>
#include<stdlib.h>
struct node
{
int num;
struct node *next;
};
struct node *head, *curr;
struct node *pos;
void addNode(int n)
{
if(head==NULL)
{
head = (struct node*)malloc(sizeof(struct node));
head->num = n;
head->next = NULL;
curr = head;
}
else
{
while(curr != NULL)
{
pos = curr;
curr = curr->next;
}
curr = (struct node*)malloc(sizeof(struct node));
curr->num = n;
curr->next = NULL;
pos->next = curr;
}
}
void printList()
{
curr = head;
while(curr != NULL)
{
printf("%d",curr->num);
curr = curr->next;
}
}
int main()
{
head = NULL;
curr = head;
int i, a[] = {4,5,1,2,3,9,0};
for(i=0;i<7;i++)
{
addNode(a[i]);
}
curr = head;
printList();
}
This seems to have solved my problem. I figured it out though. Thanks for all your help.