Hello I am so confused about this, I hope you can help me. Here is my code:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
struct node{
int x;
struct node *next;
struct node *prev;
};
typedef struct node NODE;
NODE * create(int data)
{
NODE *newn;
newn=(NODE*)malloc(sizeof(NODE));
newn->x=data;
newn->next=NULL;
newn->prev=NULL;
return newn;
}
int insert(NODE *list, int data)
{
NODE *temp,*news;
temp=list;
if(list==NULL)
{
list=create(data);
return 0;
}
}
int main()
{
int put;
NODE *mList=NULL;
clrscr();
printf("data: ");
scanf("%i",&put);
insert(mList,put);
}
It is a very simple doubly linked list but I cannot even start inserting because I cannot even put value into the first node. When I create the new node in create, the newn->x will have the right value, and list->x (in insert) will also have the right value but when it goes back to main, mList->x is still 0.
You're passing the mList pointer by value, therefore it resets when the function returns.
Switch to
insert(NODE** list, int data)
and pass it by
insert(&mList, put);
Then I think it'll work. Everytime you want a function to change something you need to pass the argument by pointer, or possibly by reference if you ever move to C++.
I am actually surprised that mList is non-zero after the call to insert.
When you pass mList to insert, a copy of the pointer (mList, which is NULL) is passed to insert. This means that whatever you do with the pointer "list" in the insert function is not reflected in the variable mList (which is outside the function).
You will need to pass address of mList so that you can change what it is pointing to.
So, change the insert method to:
insert(NODE** list, int data)
Change the assignement to list to:
*list = create(data);
and change the call to insert to:
insert(&mList, put);
Related
I am following an online tutorial which presents me with the following (simplified) code:
typedef struct {
int data;
Node* next;
} Node;
int main(){
Node *head;
init(&head);
return 0;
}
What is the purpose & functionality of the init function? I did not define it myself, however am struggling to find documentation online as well.
For starters this declaration
typedef struct {
int data;
Node* next;
} Node;
is incorrect. The name Node used in this data member declaration
Node* next;
is undefined.
You need to write
typedef struct Node {
int data;
struct Node* next;
} Node;
As for your question then in this declaration
Node *head;
the pointer head has an indeterminate value because it is not initialized.
So it seems the function init just initializes the pointer. You need to pass the pointer by reference through a pointer to it. Otherwise the function will deal with a copy of the pointer head. Dereferencing the pointer to pointer you will get a direct access to the original pointer head that can be changed within the function. That is the function can look the following way
void init( Node **head )
{
*head = NULL;
}
Pay attention to that you could just write in main
Node *head = NULL;
without a need to call the function init.
I think that the init function is gonna be implemented in the next videos. I suppose that your teacher wants to use an init function to set some values if you create a new Node (or a struct in this case) to prevent some easter eggs undefined behaviour.
The struct that will represent the node of the linked list:
typedef struct node{
int val;
struct node *next;
} node_t;
and the head of our list:
node_t *head;
Now, I wanna build a function that creates the first element in the list, of course that will be pointed by *head. I am gonna start with the correct version, in my point of view, of the function, where I used a pointer who points to head, namely a double pointer:
void createFirstElement(node_t **head, int value){
*head=NULL;
*head=malloc(sizeof(node_t));
(*head)->val=value;
(*head)->next=NULL;
}
When I used that version of createFirstElement I got the value of the node printed. However I have a question for my first version of createFirstElement which didn't worked:
void createFirstElement(node_t *head, int value){
head=NULL;
head=malloc(sizeof(node_t));
head->val=value;
head->next=NULL;
}
How is this version different from the one with double pointers? I am still getting the head pointer in parameter (instead of a pointer that points to head) and make all the changes inside.
Thanks everyone in advance!
C uses "call by value", so in the second version you are working with a copy of node_t *head. When the function returns, the head which was passed to the function remains unchanged.
I wrote a method to merge two sorted linked lists(LLs are in ascending order) into one. By using double pointer I passed address of my head pointer from calling function(main) to the called function(mergeSortedLL).
//definition of listNode
struct ListNode{
int data;
struct ListNode *next;
};
void mergeSortedLL(struct ListNode **headA,struct ListNode *prevA,struct ListNode **headB,struct ListNode *prevB)
{
struct ListNode *currA=*headA,*currB=*headB;
static struct ListNode *finalHead=NULL;
// Base Condition
if(!currA || !currB)
{
*headA=finalHead; // this should change head in main function
printList(*headA); // LINE-1 this function prints data of linked list sequentially.
return;
}
struct ListNode *nextA=currA->next, *nextB=currB->next;
if(currA->data>currB->data)
{
if(!finalHead)
finalHead=currB; // finalhead points to head of that LL which starts with smaller value node
currB->next=currA;
if(prevB)
prevB->next=currB;
mergeSortedLL(&currA,currB,&nextB,currB);
}
else
{
if(!finalHead)
finalHead=currA; //finalhead points to head of that LL which starts with smaller value node
currA->next=currB;
if(prevA)
prevA->next=currA;
mergeSortedLL(&nextA,currA,&currB,currA);
}
}
In the main function i have created two LL
head==> -1->3->5->6->8->9 first node is -1
head2==> 0->1->4->5->7->8->9
and after calling from main
mergeSortedLL(&head,NULL,&head2,NULL);
printList(head); //Line-2
Thing that i am not able to predict is Line-1 of mergeSortedLL function always prints desired sorted LL while printList method at Line-2 in main sometimes requires head to be passed and sometimes head2 to be passed for getting desired output (0113455678899).
for instance if first LL is changed to head==> 1->3->5->6->8->9, (first node is positive 1) Line-2 requires head2 to be passed instead of head to get the desired o/p.
How it is happening as in mergeSoretedLL method by means of double pointerd headA i am changing the head (of main function) to point to finalHead.
I think somehow values of headA and headB are getting swapped but i am not able to see it here.
Somebody please explain it.
You need to assign :
*headA=finalHead;
in the if and else statement as well.i.e, as below:
if(!finalHead) { // in if case
finalHead=currB;
*headA = finalHead;
}
...
...
if(!finalHead) { // in else case
finalHead=currA;
*headA = finalHead;
}
This is because when you call from main, currA and CurrB are not NULL because *headA and *headB are not NULL. So, your code enters if or else statement based on currA->data > currB->data is true or not. Here, you assign assign the finalHead to currA or currB, but, this is not reflected in *headA (head in main). So, obviously when you print from main, you won't get the result.
So, make sure that in the first recursion level, you assign the headA to the intended node's address.
typedef struct list{
int number;
struct list *next;
}LIST;
void p(struct list *head, int pos, int data){
struct list *p=head, *q, *p_n=NULL;
int i=1;
p_n = (struct list *)malloc(sizeof(struct list));
p_n->number=data;
while ((p->next!=NULL) && (i!=pos)) {
i++;
p=p->next;
}
if(p->next==NULL){
p_n->next=NULL;
p->next = p_n;
else{
q=p->next;
p->next=p_n;
p_n->next=q;
}
}
hi people., i need som help. function p should insert data to linked list at a specific position. Everithing is fine, but this function is inserting data to position+1, and i dont know why. i will be very thankful, if you wold me help.
Thank you :)
You may start with i=0 instead of 1!
There are a few points you should take care of.
You should be passing struct list **headp rather than struct list *head, and access the information using *headp. Only then the changes made to head in your function will reflect in your calling function.
What will happen when you are inserting your first element? Your head will be NULL and accessing p->next will give you a Segmentation Fault in Linux. So you should be checking for NULL before doing anything else, and if it is not NULL then only proceed to next step. If it is NULL, you should directly assign the new node to head.
What exactly is the point of typedefing the struct if you are not using it?
This is what happens when you run your code. Say you are inserting at ith position. You will find the ith node and will add the new node to the right of it. This will make the new node i+1th.
Instead you can find the i-1th node and insert the node to it's right. Change the condition in the while loop as p->next!=NULL && i<pos
Good Luck!
I am solving a program to delete all the elements in a linked list and i encountered the following problem:
When i used a delete function with return type void, and checked if the start pointer is NULL in the main ,it wasn't and gives me absurd result
Code:
void deletes(struct node *start)
{
struct node *current,*next;
current=start;
while(current!=NULL)
{
next=current->link;
free(current);
start=next;
current=next;
}
start=NULL;
return ;
}
But if i change the return type, it works fine:
struct node *deletes(struct node *start)
{
struct node *current,*next;
current=start;
while(current!=NULL)
{
next=current->link;
free(current);
start=next;
current=next;
}
start=NULL;
return start;
}
Why is the start=NULL working in the first code?
My entire code is here
It's because in the first version you pass the list header by value, meaning the pointer to the head is copied, and you change only the copy in the function. Those changes are not visible after the function returns as no changes are made on the original copy.
Either do as you do in the second version, returning the result, or pass the pointer by reference, meaning you pass the address of the pointer (or a pointer to the pointer) using the address-of operator. Of course this means that you have to change the function as well:
void deletes(struct node **start)
{
struct node *current = *start;
/* Deleting the list... */
*start = NULL;
}
Call it like
struct node *list_head = ...;
deletes(&list_head);
Because in C, function arguments are passed by value. If you write start = NULL; inside a function, it will be ineffective outside of that function (it will only set the start pointer to NULL, which is essentially just a copy of the pointer value passed in, and it's local to the function.).
If you want to modify a function argument, you must pass a pointer to it. So,
void delete(struct node **start)
{
// ... delete ...
*start = NULL;
}
then
delete(&list);
would work.
It is because you should have (struct node **start), which can allow you to pass a pointer to the list so you can modify the list.
Currently you are only passing in a copy of the linked list to the function and therefore aren't changing the value of the actual list just a copy. Hence why when you return the copy you see the results