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
Related
//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;
}
I am trying to make linked list. I can add node one by one but I could not print the linked list as i wanted. How to print linked list node from top to bottom
#include<stdio.h>
#include<stdlib.h>
struct node{
int N;
struct node *next;
};
struct node* newNode(int number, struct node *next) {
struct node *new = malloc(sizeof(*new));
new->N = number;
new->next = next;
return new;
}
void show(struct node *head){
struct node *c;
c = head;
while (c!=NULL){
printf("%d\n",c->N);
c = c->next;
}
}
int main (void ) {
struct node *head = NULL;
head = newNode(10, head);
head = newNode(20, head);
head = newNode(30, head);
head = newNode(40, head);
show(head);
return 0;
}
Output
40
30
20
10
I am trying to print node like below
10
20
30
40
How to get above output ?
Since I understand this is probably part of an excercise, I will attempt to answer it in the style of assistance, while still giving a comprehensive answer.
I let aside the fact that you insert your elements in the head - which I am not sure it is what you want to do, and I consider the question as "How to print it backwards, once I have entered the elements correctly?".
We have to examine possible solutions on this:
1) Create a method void addToTail(Node* head, int value); That traverses the list and adds elements to the tail of the list instead of the head. Side note: this operation is time costly, as it requires O(N) time complexity. About complexities, read more here. Se also this StackOverflow question.
2) You mention the term "linked list". By what you say, you do not specify if it is a singly linked, or a doubly linked. And since you have access to the node implementation, I suggest that you add a pointer to each node that points to the previous element, thus converting your singly-linked list to a doubly-linked one.
struct node{
int N;
struct node *next;
struct node *prev;
};
And, of course, you need to update this node respectively in the operations of your list - otherwise it will not work - I let this to you.
That way, you will be able to easily iterate the list backwards then in order to print the number in the order desired.
3) You could implement a function Node * reverseList(Node* head); that "reverses" a list via iteration, and then use it to print the list reversed.
And again, I let the implementation to you. Of, course, you need to consider the list state on each time, as also if you need to reverse the list in-place or return a pointer to a new, reversed list (as the function contract above indicates).
What you need to do now, is re-read your excercise brief, stop for a moment and think: "Do I really need these solutions? Is this what is requested from me?".
If you are just entering the data in the wrong order, probably not.
But if it is specifically required from you to print the list elements backwards, then you have some good hints on how to proceed.
Recursive approach works great here:
void show(struct node *c){
if (c == NULL)
return;
show(c->next);
printf("%d\n", c->N);
}
Hi guys I'm new to linked lists, but I'm pretty sure that I know how they work, theoretically, I think I might having a syntax misunderstanding, or memory management error.
edit: My main purpose is to make a collection of lists which are indexed by the array, each array element is a head(or root) node. I'm having issues allocation dynamically this struct array.
What I'm doing is the following:
typedef struct item_list{
int item_name;
int item_supplier;
int item_price;
struct item_list *next
}node;
int i;
node ** shop_1 = (node **)malloc(shop_items_elements * sizeof(node));
for (i=0;i<=shop_items_elements;i++)
{
shop_1[i]->next=NULL;
}
I'm getting a segmentation fault while I try to give next at the element i the value of NULL.
The problem is that you are trying to allocate the memory for 20000 items as a contiguous block. Which implies that you actually haven't understood linked lists yet.
I think you are mixing up random access array functionality with pure linked lists which do not allow accessing individual items without traversing the list.
A linked list usually has a head and tail node which are initially NULL when there are no elements in the list:
node* head = NULL;
node* tail = NULL;
When adding a new node you first allocate it by using malloc with the size of a single node struct:
node* the_new_node = (node*)malloc(sizeof(node));
Initialize the struct members, specifically set next to NULL for each new node. Then use this append_node() function to append the node to the linked list:
void append_node(node** head, node** tail, node* the_new_node)
{
if(*tail == NULL)
{ // list was empty
*head = *tail = the_new_node;
}
else
{
(*tail)->next = the_new_node; // link previous tail node with new one
*tail = the_new_node; // set the tail pointer to the new node
}
Please note the pointer to pointers which are needed to update the head and tail pointers. Call the function like this for any given n you want to add:
append_node(&head, &tail, n);
Repeat this for every new node.
A much better way of encapsulating a linked list is putting the head and tail pointers into another struct
typedef struct linked_list
{
node* head;
node* tail;
} list;
and using an instance of that as first argument to append_node() (which I'll leave to you as an exercise ;)
When using such a linked list it is not possible to conveniently access the Nth node in less than O(n) since you have to follow all next pointers starting from the head node until you arrive at the Nth node.
EDIT: If you want to have the possibility to index the shop items and build a linked list from each of the elements I would suggest the following solution:
node** shop_1 = (node**)malloc(shop_items_elements * sizeof(node*));
int i;
for(i = 0; i < shop_items_elements; ++i)
{
node* n = (node*)malloc(sizeof(node));
n->next = NULL;
shop_1[i] = n;
}
You first allocate an array of pointers to node pointers which have to be allocated individually of course. Take a look at this diagram for reference:
The actual node instances may be larger than a pointer's size (unlike drawn in the diagram) which is the reason why you allocate N * sizeof(node*) in a block instead of N * sizeof(node).
Your code needs to look like this
int i;
node * shop_1 = (node *)malloc(shop_items_elements * sizeof(node));
for (i=0;i<shop_items_elements;++i)
{
shop_1[i].next=NULL;
}
Your malloc statement has allocated an array of nodes, not an array of pointers to nodes. (If that is what you wanted instead, then you would have had to initialize each pointer with a further malloc call before trying to assign a value to a field within the node pointed to.)
Good day guys, im new here to C and am trying to learn linked lists. I been trying to swap 2 nodes from within a linked list but so far have been having trouble getting it to work. The code I been trying to use causes an endless circular loop, but I don't think it is because of the if or while statement.
Take a look? Any pointers here? Help would be greatly appreciated.
Basically, the code uses a user input to search for a node based on the data inside, then it should swap the node with the data inside with the next node. Been at this for 3 hours, can anybody help? Thanks!
/conductor is the name im using of the pointer for the current node/
#include <stdio.h>
#include <stdlib.h>
struct node {
int x;
struct node *next;
struct node *prev;
};
struct node *root;
struct node *conductor;
struct node *counter;
struct node *newnode;
struct node *back;
struct node *swapper;
struct node *swappee;
struct node *blanker;
int add = 0;
int initialization = 0;
int query = 0;
int swap ()
{
printf("enter data to search from within the nodes: ");
fflush(stdin);
scanf("%d", &query);
conductor = root;
while ( conductor->next != 0)
{
if(conductor->x == query)
{
printf("\n%d\n", query);
swapper = conductor;
swappee = conductor->prev;
conductor = swappee;
conductor->next = swapper;
break;
}
else
{
conductor = conductor->next;
}
}
mainMenu ();
}
A double linked list (like the one you have) is basically an array of node, each node pointing to its neighbors. Let's say we have nodes -A-B-C-D- (A-B means that A points to B and B points to A). Let's say you want to swap B and C. You have to make 4 changes:
Make A point to C
Make C point to B and A
Make B point to D and B
make D point to B
You make only the second and the third change. So, you need to add A->next = B and D->prev=C. I hope it is clear enough.
Also, you should not fflush input streams.
If you want to swap the data:
if (conductor->x == query) {
int temp = conductor->x;
if (conductor->next)
conductor->x = conductor->next->x;
conductor->next->x = temp;
}
}
Typically that is what you will want to do. If you have a structure with several members instead of the 1 int, swapping the pointers may seem less messy in theory, but it isn't, primarily due to the fact that you must test for existence of a next/previous node so often. In truth, you'd probably want a pointer to a separate structure in such a case.
Given three nodes — previous, current, and next, pointing to current->prev, current, and current->next respectively — you must update at most 6 pointers:
next->prev = previous
previous->next = next
current->prev = next
current->next = next->next
next->next = current
current->next->prev = current
Step 2 is not necessary if previous is NULL.
Step 7 is unnecessary if current->next is NULL.
The entire thing is unnecessary if next is NULL.
If you want to swap with the previous node instead of the next, exchange any instance of the variable previous with the variable next and vice-versa as well as exchanging any instance of ->prev with ->next and vice-versa.
Overall, this requires a fair bit of branching code, which can be slow. This is why it is usually better to swap the data rather than messing with the pointers. It gets even messier when you want to swap with the previous node and you only have a singly-linked list that points to the next node because you must store yet another pointer for the equivalent of previous->prev, assuming previous exists.
I'm having trouble understanding a piece of C code that represents a linked list structure. The skeleton of the struct looks like this:
struct r{
r *next;
r **prev;
data *d;
}
struct r *rlist;
rlist can be filled by calling the following function: (skeleton only)
r* rcreate(data *d){
struct r *a = xmalloc(sizeof(*r))
a->d = d;
a->next = rlist;
a->prev = &rlist;
if (rlist)
rlist->prev = &a->next;
rlist = a;
return a;
}
How do I go about using this data structure? e.g. how to traverse rlist ?
Edit: here is the function for deleting a node in the linked list
void rdestroy(struct r *a){
if (a->next){
a->next->prev = a->prev;
}
*a->prev = a->next;
destroy(a->d); /* destroy is defined elsewhere */
}
Double prev pointer seems to allow traversing list in one direction only, while allowing easy deletion (because even though you can't access the previous element (easily), you can access the next pointer of previous element, and set it to new correct value when deleting a node.
Without seeing other related functions, it's hard to see why it is done this way. I've not seen this done, and can't immediately think of any really useful benefit.
I think this allows having simpler node deletion code, because node does not need to care if it first or not, because node's prev pointer will always have non-NULL value to a pointer it needs to modify when deleting itself. And same simplicity for insertion before a current node. If these operations are what dominate the use pattern, then this could be seen as minor optimization, I suppose, especially in older CPUs where branches might have been much more expensive.
How to traverse list
This was the question, right? You can only traverse it forward, in a very simple manner, here's a for loop to traverse entire list:
struct r *node;
for (node = rlist ; node ; node = node->next) {
// assert that prev points to pointer, which should point to this node
assert(*(node->prev) == node);
// use node
printf("node at %p with data at %p\n", node, node->d);
}
Example insertion function
This example insertion function demonstrates how insertion before a node needs no branches (untested):
struct r *rinsert(struct r *nextnode, data *d) {
// create and initialize new node
struct r *newnode = xmalloc(sizeof(struct r));
newnode->d = d;
newnode->next = nextnode;
newnode->prev = nextnode->prev;
// set next pointer of preceding node (or rlist) to point to newnode
*(newnode->prev) = newnode;
// set prev pointer of nextnode to point to next pointer of newnode
nextnode->prev = &(newnode->next);
return newnode;
}
There's no good reason to have r ** next in that structure. It's for a double linked list.
So if this thing is created you have it assigned
thisList = rcreate("my data")
now you could start with traversing it
while (thisList->next)
thisList = thisList->next.
...
Your code has many syntactical errors in it, probably because (as you say) it is a "skeleton," so it is hard to parse what the author (whether it was you or someone else) actually intended this code to do.
A simple (doubly) linked list structure looks like this:
struct node {
struct node *next, *prev; // pointers to the adjacent list entries
int data; // use whatever datatype you want
};
struct node *list = NULL; // the list starts empty
void add_entry(int new_data) {
struct node *new_entry = malloc(sizeof(struct node));
// note that in the above line you need sizeof the whole struct, not a pointer
new_entry->data = new_data;
new_entry->next = list; // will be added to the beginning of the list
new_entry->prev = NULL; // no entries currently front of this one
// in general a NULL pointer denotes an end (front or back) of the list
list->prev = new_entry;
list = new_entry; // now list points to this entry
// also, this entry's "next" pointer points to what used to
// be the start of the list
}
Edit: I'll say that if you want us to help you understand some code that is part of a larger program, that you did not write and can't modify, then please post the relevant code in a format that is at least syntactical. As others have said, for example, the use of prev in the code you posted is indecipherable, and it isn't clear (because there are other similarly confusing syntactical problems) whether that was in the original code or whether it is an error introduced in transcription.
Yang, I am not sure how comfortable you are with pointers in general. I suggest taking a look at few other linked-list implementations, it might just do the trick.
Take at look at this Generic Linked List Implementation.