I am trying to create doubly linked list with a function to add a node at the end of the list. I have two typedef structs: one for Node and one for the doubly linked list.
In insertion_last() I am getting an error when trying to set list->tail->next to new_node. The error is "pointer to incomplete class type is not allowed" and is referring to DoublyLinkedList. I suppose I have done something wrong in making the structs, but cannot quite figure out why it is not working.
#include <stdio.h>
#include <stdlib.h>
typedef struct NodeStruct
{
int data;
struct Node *next;
struct Node *prev;
} Node;
typedef struct DoublyLinkedListStruct
{
int size;
struct Node *head;
struct Node *tail;
} DoublyLinkedList;
Node* newNode(int data, Node* next, Node* prev)
{
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->data = data;
new_node->next = next;;
new_node->prev = prev;
return new_node;
};
void insertion_beginning(DoublyLinkedList* list, int new_data)
{
Node* new_node = newNode(new_data, list->head, NULL);
list->head = new_node;
if (!list->tail)
{
list->tail = new_node;
}
list->size++;
}
void insertion_last(DoublyLinkedList* list, int new_data)
{
Node *new_node = newNode(new_data, NULL, list->tail);
if(list->tail)
{
list->tail->next = new_node;
}
else
{
list->head = new_node;
}
list->tail = new_node;
list->size++;
}
You define tail and several others fields to have type struct Node *. You don't have any such struct defined.
You want to change those to use struct NodeStruct * instead.
Related
I am getting an error in the constructor for Node inside the sizeof(Node) saying "type name is not allowed" any thought ? Thank you
struct Node {
int data;
Node *next;
};
struct LinkedList {
Node *first;
int size;
};
typedef struct Node Node;
typedef struct LinkedList LinkedList;
//constructor for node
Node* createNode(int data) {
Node * newNode = malloc(sizeOf(Node));
if (data != NULL) {
newNode->data = data;
newNode->next = NULL;
return newNode;
}
return NULL;
}
malloc(sizeOf(Node))
should be
malloc(sizeof(Node))
also I suspect that there are other compiler errors; you have to do
struct Node *
rather than
Node *
I want to make a double linked list and I have a problem with accessing fields in the struct. This is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int val;
struct node * next;
struct node * prev;
}node;
void insert(int val, node **head)
{
node * temp= *head;
node * temp2=(node *)malloc(sizeof(node));
node * temp3=(node *)malloc(sizeof(node));
temp2->val=val;
temp2->prev=NULL;
temp2->next=*head;
*head=temp2;
temp2->next->prev=temp2;
}
void print(node* head)
{
node* temp=head;
while(temp!=NULL)
{
printf("%d ", temp->val);
temp=temp->next;
}
}
int main()
{ node * head=NULL;
insert(1, &head);
insert(2, &head);
print(head);
return 0;
}
I get a crash at temp2->next->prev, and I don't understand why. Am I not allowed to access the prev field of the temp2->next node? I tried writing (temp2->next)->prev but also doesn't work. Is there any way that I cant make that work?
When you insert the first node, *head, and therefore temp->next, is NULL. Check that case:
void insert(int val, node **head)
{
node *temp= malloc(sizeof(*temp));
temp->val = val;
temp->prev = NULL;
temp->next = *head;
*head = temp;
if (temp->next) temp->next->prev = temp;
}
(I've removed the unused variables and lost the cast on malloc.)
A doubly linked list should probably have a tail, too. In that case, update the tail when you append an item at the head of an empty list.
try this:
void insert(int val, node **head)
{
if(*head == NULL){
node * temp2=(node *)malloc(sizeof(node));
temp2->val=val;
*head = temp2;
}
else{
node * temp= *head;
node * temp2=(node *)malloc(sizeof(node));
temp2->val=val;
temp2->prev=NULL;
temp2->next=temp;
temp->prev = temp2;
}
}
Most likely head was not initialized
As I have understood you always insert a new node before the head though in double linked list you have to add new nodes usually at the tail of the list. As a double linked list usually have two sides then there is a sense to define two functions: push_front and push_back. Your function insert corresponds to function push_front.
Nevertheless function insert could look the following way
void insert( int val, node **head )
{
node *temp = ( node * )malloc( sizeof( node ) );
temp->val = val;
temp->prev = NULL;
temp->next = *head;
if ( *head ) ( *head )->prev = temp;
*head = temp;
}
It would be better if you would define one more structure named as for example List (or whatever) and that could be defined as
struct List
{
node *head;
node *tail;
};
Also you could add one more data member - a count of the nodes in the list, For example
struct List
{
node *head;
node *tail;
size_t count;
};
Also do not forget to write a function that would delete all nodes of the list when it is not needed any more.
The code below is adding a new node to the head of the list. I was wondering how I would change it so that it would add a new node to the tail(end) of the list instead of the head.
typedef struct node{
int data;
struct node *next;
struct node *prev;
} Node, *NodePtr;
typedef struct linkedlist{
NodePtr head;
NodePtr tail;
} LinkedList, *LinkedListPtr;
void insertTail(LinkedListPtr list, int data){
NodePtr newNode;
newNode = (NodePtr)malloc(sizeof(Node));
newNode->data = data;
newNode->next =NULL;
newNode->prev =NULL;
/* add it to the beginning of linked list*/
if (list->head==NULL){ /*linked list is empty*/
list->head=newNode;
list->tail=newNode;
}
else {
//connect new node to the head of the list
newNode->next = list->head;
list->head->prev=newNode;
//reassign head of the list
list->head = newNode;
}
}
I am new to programming. I am trying to learn C and pointers, but it is giving me much trouble.
I got the following error trying to implement a singly linked list. I searched online, and I couldn't find someone who had an error just like mine, or perhaps I just didn't couldn't make sense of it with my problem.
The following is the error I received:
warning: incompatible pointer types initializing 'NODE *'
(aka 'struct node *') with an expression of type 'struct NODE '
[-Wincompatible-pointer-types]
NODE temp = (*l)->head;
NODE* temp = (*l)->head;
In main, I passed the address of the variable of type LIST. So, I thought I had to dereference 'l', to get the address of where the LIST type is located, then I had to dereference with an arrow to get the address of where the NODE is located. Where am I confused? I do appreciate the help.
Below you will see the code I have written:
typedef struct node {
int value;
struct node* next;
}NODE;
typedef struct list{
struct NODE* head;
}LIST;
void insert(LIST** l, int x){
if((*l)->head == NULL){
NODE* new_Node = (NODE*) malloc(sizeof(NODE));
new_Node->next = NULL;
new_Node->value = x;
}
NODE* temp = (*l)->head;
while(temp->next != NULL){
temp=temp->next;
}
NODE* new_Node = (NODE*) malloc (sizeof(NODE));
temp->next = new_Node;
new_Node->next = NULL;
new_Node->value = x;
}
int main(){
LIST *l = (LIST*) malloc(sizeof(LIST));
insert(&l, 5);
return 0;
}
I guess your problem is here :
typedef struct list
{
struct NODE* head;
}LIST;
just remove struct keyword before NODE
typedef struct list
{
NODE* head;
}LIST;
or
typedef struct list
{
struct node* head;
}LIST;
Also you need to initialize the head with NULL to make this condition to wwork
if((*l)->head == NULL) .....
so when you create your list add l->head = NULL;
LIST *l = malloc(sizeof(LIST));
l->head = NULL;
And the last one (i hope) when you create your first node, you forget to assign head to it, and return in order not to add the first element twice
if((*l)->head == NULL)
{
NODE* new_Node = malloc(sizeof(NODE));
new_Node->next = NULL;
new_Node->value = x;
(*l)->head = new_Node;
return;
}
And BTW, don't cast malloc results in C
This:
typedef struct list{
struct NODE* head;
}LIST;
Should be this:
typedef struct list{
NODE* head;
}LIST;
Tested and compiles fine with that change.
Your use of *l is correct. The problem is with the line:
NODE* temp = (*l)->head;
The left-hand side is NODE *, which is the same as struct node *, however the right-hand side is struct NODE *.
C is case-sensitive, struct node and struct NODE are different types. Also, the namespace of struct tags is separate to that of other types, so NODE and struct NODE are also different types.
I think you meant, in LIST's definition, that struct NODE* head; should be NODE* head;. There is no warning generated on that line, because in C it's legal to implicitly declare a struct type just by mentioning it (i.e. this line declares the new type struct NODE also).
There is code repetition in your insert function. You should not use the struct keyword before NODE in the second typedef statement because NODE is already an alias for the type struct node. That's why you are getting the warning mentioned in your question. Also, you should not cast the result of malloc. Please read this - Do I cast the result of malloc?
I suggest the following changes to your code.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *next;
} NODE;
typedef struct list {
NODE *head;
} LIST;
void insert(LIST **l, int x) {
// do not cast the result of malloc.
// also, do not repeat the type on the rhs.
// create the new node to be inserted
NODE *new_Node = malloc(sizeof(*new_Node));
new_Node->next = NULL;
new_Node->value = x;
NODE *temp = (*l)->head;
// check if the head of the list is empty
// if yes, simply assign the new node to head
// and return
if(temp == NULL) {
(*l)->head = new_Node;
return;
}
// reach the last node in the list
while(temp->next != NULL)
temp = temp->next;
// insert the new node to the end of the list
temp->next = new_Node;
}
int main(void) {
LIST *l = malloc(sizeof(*l));
insert(&l, 5);
insert(&l, 10);
// print the value of the head node
printf("%d\n", l->head->value);
// print the value of the next node
printf("%d\n", l->head->next->value);
NODE *head = l->head;
NODE *temp = NULL;
// free the nodes in the list
while(head != NULL) {
temp = head;
head = head->next;
free(temp);
}
// free the pointer to the
// head of the list
free(l);
return 0;
}
I have some errors to my code and I still don't understand why it does not work.
I have the following code snippet:
void insertBefore(List *lista, Node **node, Node *newNode)
{
newNode->prev = (*node)->prev;
newNode->next = (*node);
if((*node)->prev == 0)
lista->first = newNode;
else
(*node)->prev->next = newNode;
(*node)->prev = newNode;
}
And I call it as:
insertBefore(lista,lista->first, newNode);
And the error is :
error: dereferencing pointer to incomplete type
What I tried and works(no errors but crashes when I debug):
void insertBefore(List *lista, Node **node, Node *newNode)
{
Node *anotherNode = (*node)->prev;
newNode->prev = (*node)->prev;
newNode->next = (*node);
if((*node)->prev == 0)
lista->first = newNode;
else
anotherNode->next = newNode;
(*node)->prev = newNode;
}
Here are the structures I use:
typedef struct NodeT
{
struct nodeT *prev;
struct nodeT *next;
int key;
}Node;
typedef struct ListT
{
Node *first;
Node *last;
Node *current;
}List;
Now, my question is: is there any issue when the compiler parses? I really don't figure it out.
Watch the capitalization!
typedef struct NodeT /* uppercase N */
{
struct nodeT *prev; /* lowercase N */
NodeT and nodeT are different identifiers