So I have created two structures LIST (consists of head and last pointer) and NODE (consists of next and previous pointer). I have a function create_list (LIST *p) that does the following:
Sets the head and last pointer to NULL
Asks the user to enter the no of nodes for the list and also lets user enter the value and it inserts a node in an orderly manner (increasing order)
Once done, it displays the list
So I created two LIST pointer variables and tried making two doubly linked list, it works perfectly for the first list but the second list does not get initialized.
Here is the code:
void create_list(LIST *p){
int x;
printf("enter no of elements to enter\n");
scanf("%d", &x);
printf("creating a list of size %d\n", x);
p->head =NULL;
p->last=NULL;
printf("initialised list\n");
for(int i =0; i<x; i++){
ins(p);
}
display(p);
}
int main(){
LIST* list1, *list2;
create_list(list1);
create_list(list2);
return 0;
}
LIST* list1, *list2; isn't doing what you think its doing. These pointers are pointing at a random location in memory. They need to point at a LIST type somewhere. In other words, there is no LIST in existence in your code. This is undefined behavior, so the fact that the first one initialized correctly was only by chance.
For example, if I wanted them to exist in main's stack:
LIST list1, list2;
create_list(&list1);
create_list(&list2);
Now 2 LISTs exist, and we have passed their addresses to create_list.
Related
I just learned the concept of a linked list in C, and tried implementing it. What I did was create a pointer head, and a pointer itr. To create a new node I would initialize a node normally (without using pointers), and then attach a pointer to it.
struct node temp; //A single node contains a value 'num' and a pointer to the next node.
temp.num=x;
temp.next=NULL;
if(head==NULL){
head=&temp;
}
else{
itr=head;
while(itr->next!=NULL){
itr=itr->next;
}
itr->next=&temp;
}
This method is not working, and based on my limited knowledge of pointers in C, I cannot figure out why. I know that the right way to do it is by using malloc to create new nodes, but I need to know why this method does not work.
Full Program:
#include <stdio.h>
struct node{
int num;
struct node *next;
};
int main(){
struct node *head=NULL;
struct node *itr;
struct node temp;
int choice;
printf("1. Enter new Node, 2. Traverse all nodes, 3. Exit.");
int x;
while(1){
printf("\nEnter your choice: ");
scanf("%d", &choice);
if(choice==1){
printf("Enter value: ");
scanf("%d", &x);
temp.num=x;
temp.next=NULL;
if(head==NULL){
head=&temp;
}
else{
itr=head;
while(itr->next!=NULL){
itr=itr->next;
}
itr->next=&temp;
}
}
else if(choice==2){
if(head==NULL){
printf("Empty List");
continue;
}
printf("The values are: ");
itr=head;
printf("%d ", itr->num);
while(itr->next!=NULL){
itr=itr->next;
printf("%d ", itr->num);
}
}
else{
break;
}
}
}
A linked list generally consists of several nodes, in which each node points to the next node in the list. The last node in the linked list should point to NULL to mark the end of the list.
However, you have only allocated memory for a single node. Therefore, you will only be able to store a single node in the linked list.
The code for adding the first node to the linked list is correct. However, the code for adding a second node cannot work, because you have not allocated any memory for the second node.
What your code for adding the second node is actually doing is overwriting the first node, and making this first node point to itself. That is why you are getting an infinite loop, if you attempt to print the linked list afterwards.
Therefore, I suggest that you instead use malloc for allocating memory for the nodes. That way, you won't be limited to a single node.
You must show your whole code.
I guess , in your case, if you define a function like this, the temp elem is funciton local variable, you need use malloc to make it accessable out of the function.
int addNode(struct node *head, inx x) {
struct node temp; //A single node contains a value 'num' and a pointer to the next node.
temp.num=x;
temp.next=NULL;
if(head==NULL){
head=&temp;
}
else{
itr=head;
while(itr->next!=NULL){
itr=itr->next;
}
itr->next=&temp;
}
}
//linked_list_1
#include<stdio.h>
#include<stdlib.h>
struct list
{
int data;
struct list *link;
};
int main()
{
struct list *ll=NULL, *tp=NULL;
int n=3, i;
ll=(struct list *)malloc(sizeof(struct list));
scanf("%d",&ll->data);
for(i=1; i<n; i++)
{
tp=(struct list *)malloc(sizeof(struct list));
scanf("%d",&tp->data);
ll->link=tp;
ll=ll->link;
}
ll->link=NULL;
while(ll)
{
printf("\n%d",ll->data);
ll=ll->link;
}
}
//linked_list_2
#include<stdio.h>
#include<stdlib.h>
struct list
{
int data;
struct list *link;
};
void linked_list(struct list *,int);
int main()
{
struct list *ll=NULL;
int n=3;
ll=(struct list *)malloc(sizeof(struct list));
linked_list(ll,n);
while(ll)
{
printf("\n%d",ll->data);
ll=ll->link;
}
}
void linked_list(struct list *kk, int n)
{
struct list *tp=NULL;
int i;
scanf("%d",&kk->data);
for(i=1; i<n; i++)
{
tp=(struct list *)malloc(sizeof(struct list));
scanf("%d",&tp->data);
kk->link=tp;
kk=kk->link;
}
kk->link=NULL;
}
Both the programs are same, the second program is linked list creation using a function: void linked_list(struct list *kk, int n) The first program is also linked list creation but without any function. Second program is working properly but the first program is not working in the right way.
If the inputs are 2 5 4 for both the programs, second program output is 2 5 4 but the first program output is only 4.
Why the first program is not working in the right way? What is the reason?
The problem with the first program is that you are moving the head of the linked list while you are taking the input. So when you are done taking the inputs basically the head of the linked list is now at the last node of it. Then when you are trying to print out the linked list you are just getting the last node of it since the head got moved to there when you took the last input.
Ideally you should use the temporary pointer, align it with the head pointer of the linked list and then take the input, assign it and move it and keep on building the linked list using it only. The head pointer (here ll) of the linked list once initialized should not be move like this:
ll=ll->link; //Wrong!
Until it is absolutely required to do so. This will result in a truncated linked list and you will lose your nodes.
Ideally your code should be something like this:
ll=(struct list *)malloc(sizeof(struct list));
tp = ll; //Align the temporary pointer with the head of the linked list.
scanf("%d",&tp->data);
for(i=1; i<n; i++)
{
//Allocate memory to the link of the temporary pointer since it is also a type of struct list.
tp->link=(struct list *)malloc(sizeof(struct list));
scanf("%d",&tp->link->data);
tp = tp->link; //Move only the temporary pointer.
}
tp->link=NULL; //Finally assign NULL when done taking inputs.
Notice carefully I am only using the temporary pointer to do everything.
The reason why the second program works is because you are passing the address of the head pointer to the function that you are using to build the linked list. Now this function gets a copy of the address in kk that is the starting address of the linked list and builds the linked list there using it. But back in the main() the ll pointer is still holding the original address where you initially allocated the memory. Hence after constructing the linked list when you are back in the main() to print it, you start with the actual head of the linked list still hold by ll and you are able to print out the entire linked list.
But this still has the same flaw that I mentioned earlier. You are moving the head of the linked list while printing it (i.e. ll).
while(ll)
{
printf("\n%d",ll->data);
ll=ll->link; //This is wrong!
}
So after you are done printing the linked list your head of the linked list is now NULL. So if you want to do something with the actual linked list after printing it, it is now not possible since you have made the head NULL. So again the solution is use a temporary pointer align it with the head of the linked list and then use it to print out the linked list. Something like this:
struct list *tp = ll;
while(tp)
{
printf("\n%d",tp->data);
tp=tp->link;
}
Hello guys could you please help me in writing a procedure to reverse the pointers in a linked list . for example A->B->C->D would become A<-B<-C<-D without using extra linked list .
Edit:
------ okay guys so i have been looking for solution for this problem here is the code in case u want it :
void reverse_list(){
struct node *next, *current,*previous;
previous = NULL;
current =head;
while(current != NULL){
next = current->next;
current->next = previous;
previous=current;
current = next;
}
head = previous;
}
You could think of the list as a stack. Then you could easily reverse such a list by "popping" the nodes and "pushing" them into a new list.
The above could be done both destructively (destroying the old list) and non-destructively (creating the new list as a reversed copy of the original list).
As you didn't mention if you are implementing the linked list yourself or not.
So firstly I am assuming that you are doing it by yourself. So following is an implementation of linked list and again its pointers are reversed to make the link list reverse. You can take an idea from it.
#include<stdio.h>
#include<stdlib.h>//for using malloc
struct Node//Defining a structure for linked list's node
{
int info;//assuming it is an integer linked list
struct Node *link;//this pointer links a node to it's immediate neighbor node
};
struct Node *head=NULL,*temp;//some initializations and declarations
void insertion(int data)//To insert elements to linked list
{
struct Node *ptr;
ptr=malloc(sizeof(*ptr));//creating a new node for the newcomer
ptr->info=data;//taking the given integer value for the node to hold
//initializing with null as the current node may be the last node and
//if it is then it will point nobody
//...but if it is not when a new node comes in the future it will eventually be
//replaced to point the newcomer
ptr->link=NULL;
if(head==NULL)//head still null means we are creating the first node
{ //handling the head separately as it has no parent node
head=ptr;
temp=ptr;//copying the current node's pointer to temp such that we can
//find it as a parent of next node
}
else//for the rest of the nodes' creation
{
//as temp is the pointer to the previous node, so previous node is linking
//to its next node, i.e, the current node
temp->link=ptr;
//updating the temp to point the current node such that it can act as a parent node
//when the next node comes
temp=ptr;
}
}
void reversePointers()
{
struct Node *trav,*from=NULL,*temp;
for(trav=head;;)
{
if(trav->link==NULL)//if we have reached to the end
{
head=trav;//then the reverse linked list's head should point to the last element
trav->link=from;//and making the second last node as it's next node
break;
}
temp=trav;//saving current node pointer to update the "from" pointer
trav=trav->link;//advancing current node pointer to forward
temp->link=from;//making the current node to point to it's previous node
from=temp;//saving current node's pointer which will be used in next iteration
}
}
void traverse()//to traverse the nodes
{
struct Node *ptr=head;
while(ptr!=NULL)
{
printf("%d ",ptr->info);
ptr=ptr->link;
}
printf("\n");
}
int main(void)
{
int i,n,t;
printf("Enter Number of elements: ");
scanf("%d",&n);
printf("Enter Elements: ");
for(i=0;i<n;i++)
{
scanf("%d",&t);
insertion(t);
}
printf("Before reversing the pointers the elements are: ");
traverse();
//let's reverse the pointers to make the list to go backward
reversePointers();
printf("After reversing the pointers the elements are: ");
traverse();
}
Secondly if you are using STL list then the approach is quite straightforward. Just use,
your_list_name.reverse()
Again if you want to reverse the STL list just for iteration purpose then there is no need to actually reverse it. Instead you can use reverse iterator as following (say for an integer list):
for(list<int>::reverse_iterator it=your_list_name.rbegin();it!=your_list_name.rend();it++)
{
//do whatever you want
}
I have a program where details are taken by a user for a survey. It contains details of a person with a pps as a unique identifier. When adding a newNode to the list and checking the PPS it does not recognise if the number is the same in any of the nodes. Adding a printf into the loop to show the current pps gives a nullptr exception. I have tried not using **head_ptr replacing with *head_ptr however this gives more errors down in the rest of the code where the node is added to the list.
//a new node is created which is filled with info. Some vaidation is done such as PPS number uniqueness and the node is added to the list
//in this function the node is added to the very front of the list. Note: the sorting does not happen here without sorting it would be a list of the most recently enetered items
//a second function will carry out the sort
void addSurvey(struct survey** head_ptr)
{
int inputPPS,inputAge,inputSmoker, inputDrink, inputExer, inputIncome;
int scanfBoolean;
struct survey *temp;
struct survey *newNode;
temp = *head_ptr;
newNode = (struct survey*)malloc(sizeof(struct survey));
printf("\nPlease enter your PPS number (Number must be unique)\n");
scanf("%d", &inputPPS);
while (temp != NULL)
{
if (inputPPS == temp->surveyDetails.ppsNo)
{
printf("\nPPS you have entered is not unique. \n\n");
free(newNode); free(temp);
return;
}
temp = temp->next;
printf("\nChecking list. PPS is %d\n\n", temp->surveyDetails.ppsNo);
}
newNode->surveyDetails.ppsNo = inputPPS;
You are freeing node once you found it
free(temp);
In this case after you return from this function addSurvey the pointer pointed to by struct survey** head_ptr points to freed memory and probably you use it incorrectly.
Even worse, when you assign new value to temp and you might have assigned a NULL to it, you are not checking this and you try to access pointer to that unknown memory to print integer:
temp = temp->next;
printf("\nChecking list. PPS is %d\n\n", temp->surveyDetails.ppsNo);
You do not link your new node (newNode) to the list leaving the list empty. You have to add
temp->next=newNode;
is an appropriate place
I need to make a program that has (at most) 50 linked lists. Basically, my program generates some messages and based on a indicator that comes in the front of my string, I need to put the message in the right linked list.
I don't know if it is clear enough but I will try to show part of my code (the important part). The function I made to add a new element (on the top) of the linked list is the following:
void InsertLL (News p, char M[]) {
char * text = malloc(strlen(M)+1);
strcpy(text, M);
News s,t;
t = malloc(sizeof(struct List));
t-> Text = text;
s = p;
p = t;
p-> next = s;
}
My struct List (the type of the elements of my lists) contains a char pointer (called text) and a pointer to the next element of the list.
Simulating my program, suppose that I received a message that needs to be put in the linked list where the begin is pointed by the pointer p[0]. So I create a new element (forget the case that the list is empty, I already made this one) and add in the top of my list using the function I've shown.
Now, suppose that I received another message that needs to be put in the next pointer p[1]. If I print p[0] -> Text, I get the text of p[1]->Text.
I mean, if I add a new element in the list pointed by p[i], all the previous texts p[i] -> Texts gets the new text of this new element. I have no idea what am I doing wrong.
I don't know if it is enough to help me, if more information is needed, just tell me.
Problem with your code is you are not maintaining the list of nodes. you are overwriting the same node again and again.
Algo:
If no node then create one.
If nodes are present then navigate to end node.(You can use tail
pointer for quicker access).
Append the node at the end.
Creating Node:
Declare a node type pointer.
Allocate memory to it.
Update the content of the node.
Set the next pointer of the node to null.
Add this node to end of the list.
ex. inserting node 3 in the list of node 1 and node 2.
This is the general approach that you can use
typedef struct node{
int val; //you can use your text here
struct node* next;
}NODE;
struct node* head=0;
int addNode(int v){
if(head==0){ //checking for empty node.
struct node* n=malloc(sizeof(NODE));
n->val=v;
head=n;
}
else{
struct node* temp=head;
while(temp->next != 0) //Navigating till end
{
temp=temp->next;
}
struct node* n=malloc(sizeof(NODE)); //allocating memory
n->val=v; //you need to use strcpy for string here.
temp->next=n; //adjusting pointers
n->next=0;
}
}
You can check this demo created by me for Double linked List http://ideone.com/s6TtUX