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);
}
Related
I want to build a graph that creates a new parent node by merging two child nodes. The code below is supposed to merge node a and b into a parent node c. Then, nodes a and c to create a parent node d:
a b
|---|
|
a c
|---|
|
d
When I try to free the graph starting at node d I get a segmentation fault and I don't know why. Somehow it works if I don't use the same node twice in the graph. However, I want to be able to use the same node more than once. Can someone please tell me what am I missing here?
#include <stdlib.h>
struct Node {
int data;
struct Node *child1;
struct Node *child2;
};
struct Node *NewNode(double data) {
struct Node *node = NULL;
node = malloc(sizeof(*node));
if (node == NULL) {
return node;
}
node->data = data;
node->child1 = NULL;
node->child2 = NULL;
return node;
}
struct Node* merge(struct Node *self, struct Node *other) {
struct Node *node = NewNode(-1);
node->child1 = self;
node->child2 = other;
return node;
}
void free_graph(struct Node **node) {
if (*node != NULL) {
free_graph(&(*node)->child1);
free_graph(&(*node)->child2);
free(*node);
*node = NULL;
}
}
int main(void){
struct Node *a = NewNode(1);
struct Node *b = NewNode(2);
struct Node *c = merge(a, b);
struct Node *d = merge(a, c);
free_graph(&d);
}
It does not work because your "tree" does not match your illustration, and is in fact technically not a tree. What you have looks like this:
You need to make a copy instead of reusing a node if you want a tree.
In order to free everything in a graph like this, I'd suggest having a separate linked list to keep track of everything you need to free.
If you don't want to do that, or cannot do that for some reason, it gets more complicated. Performing an operation an all nodes in a tree is trivial, but for a general directed graph it's slightly more complicated. I guess this answer could help, and if not, it at least gives you an idea about what to search for:
Finding list of all nodes in a directed graph
I assume you could do something like this pseudo:
getAllNodes(root, nodes)
if root // NULL check
if not node in nodes // If it's the first time we visit the node
// Add this node to the list of visited nodes
nodes = nodes + [root]
// And then call this function recursively on the children
getAllNodes(root->left, nodes)
getAlLNodes(root->right, nodes)
nodes = []
getAllNodes(root, nodes)
for node in nodes
free(node)
Trees have the nice feature that they never contain loops. But directed graphs do, so you have to have some check to see if a node is already visited. Note that in order for this to work, it has to be called from the root. Or to be more precise, every node needs to be reachable from the node. But that's not so different from a tree.
I guess you could somehow move the free inside to create a freeAllNodes() function, but this is more flexible. Maybe you want a list for other purposes. So my suggestion in that case is to just make freeAllNodes() call getAllNodes().
I could write an implementation for the above, but since C does not provide library functions for linked lists, that would mean including a lot of extra code.
You put a into the intended tree twice, so free_graph attempts to free it twice. Calling free twice on the same address from the same original allocation is improper.
If you want to have a true tree, do not put any node into it twice. If you want to have a data structure that can have the same node in it twice, either use separate copies of the node (e.g., two different allocations for struct Node with the same value for data) or make provisions in the data structure to avoid freeing it twice (for example, add a reference count to struct node to count how many times it is currently in the tree, and free the node only when its reference count reaches zero).
I've created a doubly linked list, filled it with values and now I want to delete it and remove all the values to avoid memory leaks. Here's what I wrote as well as the structs that were used when creating the doubly linked list. Both those functions will be called towards the end of the main function.
struct node
{
struct node *next;
struct node *prev;
char *value;
};
// The type for a list.
typedef struct list
{
struct node head;
} List;
// The type for a list position.
typedef struct list_pos
{
struct node *node;
} ListPos;
void list_destroy(List *lst)
{
List p,q;
p = *lst;
while (p)
{
q = p.head->next;
free(p);
p = q;
}
*lst = NULL;
}
// Remove the value at the position and return the position of the next element.
ListPos list_remove(ListPos pos)
{
}
You appear to have the right general idea: you walk the list and free each node, making sure to grab any needed data from each node (in particular, the pointer to the next node) while the node holding it still exists. Your case differs from some that you might have seen, however, because instead of handling the overall list via a bare pointer to the head node, you have a separate object, of a separate type (List / struct list), to represent the list itself. This approach has much to recommend it, including, especially, the use of (apparently) a dummy head node, which provides for a variety of algorithmic simplifications. This is usually how I write a linked list.
But because struct list is not struct node, you cannot set a list pointer equal to a node pointer. Instead, create a struct node * to track your position. The first node to free would be the one referenced by struct node *to_free = lst->head.next, and the one after that would be the one referenced by to_free->next.
Note that you might need to free the struct list, too.
Considering a list like 1->2->3->4->5
Tlist is made like this:
typedef struct node{
int info;
struct node *link;
}Tnode;
typedef Tnode *Tlist;
I got the function listDeleteOdd which is built like this
Tlist listDeleteOdd(Tlist list) {
if (list == NULL)
return NULL;
if (list->info % 2 == 1) {
Tnode *node = list->link;
DeleteNode(list);
return listDeleteOdd(node);
}
Tnode *node = listDeleteOdd(list->link);
list->link = node;
return list;
};
Delete node just frees the memory of the given node ofc.
By the way I dont understand how the value Tnode *node after the second if changes . Like it should be NULL couse the cycle return NULL when the prototype "list" reaches the end. After the cycle reaches the end what happens to node and the end the 'return list;' what it returns ??
I studied recursion some months ago and now it's all so confusing . There is there someone who can explain me how the whole function works properly couse i kinda understand how it works but i think there are some steps which are not really clear in my mind. Thx for the patiente in advance .
The key is defining what listDeleteOdd() does. It returns a pointer to a list of nodes which is either empty or contains only even values — a 'clean list'.
Internally, it does that in three different operations:
The input list is empty (NULL); return NULL (base case).
The first node in the list is odd; capture the next node, delete the current node; recurse to return the clean list starting at the next node.
By elimination, the first node in the list is even. Capture the list of even values starting at the next node (recurse). Make the current node's next pointer (link) point to the clean list, and return the current node as the start of the (now clean) list.
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!
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.