Any idea why I’m losing links? - c

I have started to learn about linked lists, and I have written this code.
It should be a recursive call to create a new link in a linked list in c.
But, if you’ll check the output, you’ll see it’s passing over the middle links.
I don’t know why I’m losing the middle links.
Btw, I do have a destroy function in my code, I just didn’t write it here.
I do have a different version of a working code, I don’t ask for solutions, I’m only asking why this recursive idea doesn’t work.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct node {
int data;
struct node *next;
}node;
node *create(node **head, int data)
{
if(!*head) {
*head = malloc(sizeof(node));
assert(*head);
(*head)->data = data;
(*head)->next = NULL;
return *head;
}
node *new = NULL;
new = create(&new,data);
(*head)->next = new;
return *head;
}
void display(node *head)
{
assert(head);
node *current = head;
do
{
printf("%d\t",current->data);
current = current->next;
}while(current);
}
int main()
{
int count = 0, data = 0;
node *head = NULL;
printf("Enter list count:\n");
while(count <= 0){
scanf("%d",&count);
if(count <= 0) printf("\nEnter a valid number:\n");
}
while(count){
scanf("%d",&data);
head = create(&head,data);
count--;
}
printf("\nHere are the elements:\n");
display(head);
return 0;
}

As implemented create() either adds a new node to the tail or iterates to the next linked node. Logic changed to affect that. It's confusing that the first argument is called head to changed it to n. Changed main() to retain the head and made the program non-interactive for ease of testing. Recatored display to use a for() loop:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
node *create(node **n, int data) {
if(!*n) {
*n = malloc(sizeof(**n));
assert(*n);
(*n)->data = data;
(*n)->next = NULL;
return *n;
}
node *n2 = (*n)->next;
(*n)->next = create(&n2, data);
return n2;
}
void display(node *head) {
assert(head);
for(node *c = head; c; c = c->next) {
printf("%d\t", c->data);
}
}
int main() {
node *head = NULL;
node *tail = NULL;
for(int i = 0; i < 10; i++) {
tail = create(&tail, i);
if(!head) head = tail;
}
display(head);
return 0;
}
and it displays:
0 1 2 3 4 5 6 7 8 9
If you compile your code with NDEBUG (some folks do that for production) then your code no longer has any error handling.

Thank you all for your answers. I see the problem now, after “explaining to the duck” a thousand times. In function create(), under the if() block, I assigned (*head)->next = new; without first making it point to the last link, so it’s just over write the next link in every call to the function.
The solution is:
Add a “current” pointer points to the head(to not lose it’s value)
Iterate through the list until we find the last link,
assign current->next the value of new.
Here is the fixed section:
node *new = NULL;
new = create(&new,data);
node *current = *head;
while(current->next) current = current->next;
current->next = new;
return *head;

Related

Different results between online C compiler and compiling in cmd while trying to implement linkedlists

Actually the title is pretty self explanotary, I implement the linkedlist in online C compiler and the code correctly adds elements to the list, prints the list and then deletes the last element of the linkedlist. But when I compile the program in MinGW on cmd it enters a infinite loop, it doesn't even show the elements added just some random numbers looping and I haven't been able to pin-point the problem.
#include <stdlib.h>
typedef struct node{
int data ;
struct node *next ;
}node;
//
node* newNode(int value){
node *n = malloc(sizeof(node));
n->data = value;
n->next = NULL;
}
//
typedef struct list{
node *head;
node *tail;
}list;
//
list* add(list *liste, int value){
node *n = newNode(value);
if(liste->tail == NULL){
liste->tail = n;
}
n->next = liste->head;
liste->head = n;
return liste;
}
//
void gez(list *liste){
node *ix = liste->head;
while(ix != NULL){
printf("%d\n",ix->data);
ix = ix->next;
}
}
//
list* cikar(list *liste){
node *ix = liste->head;
while (ix->next != liste->tail){
ix = ix->next;
}
liste->tail = ix;
ix->next = NULL;
return liste;
}
//
int main(){
list *l = malloc(sizeof(list));
l = add(l,4);
l = add(l,8);
l = add(l,16);
gez(l);
l = cikar(l);
printf("\n");
gez(l);
return 0;
}
Your code has several bugs:
head and tail have no initial value. This will cause indefinite behaviour in add. Change malloc to calloc will by default NULL initialize them or you have to manually do so.
newNode has no return value. Return n.
You didn't free memory when removing node. Before setting ix->next = NULL free(ix->next).

How to print the first node from a linked list of structs?

Below is a Minimal Reproducible Example from my code. What I am doing is that I am inserting data in a list of structs and printing them on the console.
I want to print from each link only the first element that is inserted into each list of structs.
But how is that possible when instead of data in my struct I have:
typedef struct Node
{
int rollnumber, src, dst;
double gentime;
struct Node *next;
} Node;
(rollnumber, src, dst,gentime are the information I am reading from text files, but the reading code is not nessacary, so I wrote it with testdata.)
MINIMAL REPRODUCIBLE EXAMPLE
#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct Node
{
int data;
struct Node* next;
} Node;
int push_front(Node** head, int data)
{
Node* new_node = malloc(sizeof(Node));
int success = new_node != NULL;
if (success)
{
new_node->data = data;
new_node->next = *head;
*head = new_node;
}
return success;
}
void output(Node* head)
{
for (Node* current = head; current != NULL; current = current->next)
{
printf("%d ", current->data);
}
}
void display(Node** set, int i)
{
output(set[i]);
putchar('\n');
}
int main(void)
{
int testdata = 1;
Node* link[N] = { 0 };
struct Node* head = NULL;
for (int i = 0; i < N; i++) {
push_front(&link[i], testdata++);
push_front(&link[i], testdata++);
}
for (int i = 0; i < N; i++) {
printf("link[%d]:", i);
display(link, i);
}
}
If you only want to print the first element of each link list, just do not loop in output:
void output(Node* head)
{
printf("%d ", head->data);
}
If I am right you want the first element of the list right ??
If so than the way you are working you are pushing the new node in front of old node, so your first node is now the last in the line, so all you need to do is to iterate the list till Node* next == null, and that node will be your answer
Node *getLastInLine( Node *Head){
Node *ptr;
ptr = Head;
if( ptr == NULL) return NULL;
while(ptr-> next != NULL){
ptr = ptr->next;
}
return ptr;
}

LinkedList length, access and implementation via a heap. C

I am trying to print the length of a linked list I created in another .c file called linklist.c from the main.c file. It is not working and I believe is has something to do with pointers and/or memory management over all. I call into question the heap mainly here. some guidance would be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include "node.h"
int main()
{
printf("Hello world!\n");
struct node* mylist = BuildOneTwoThree();
int length = Length(mylist);
printf(mylist->data);
printf(length);
return 0;
}
#include "node.h"
#include <stdio.h>
#include <stdlib.h>
// Return the number of nodes in a list (while-loop version)
int Length(struct node** head) {
int count = 0;
struct node* current = head;
while (current != NULL) {
count++;
current = current->next;
}
return(count);
}
/*
Build the list {1, 2, 3} in the heap and store
its head pointer in a local stack variable.
Returns the head pointer to the caller.
*/
struct node* BuildOneTwoThree() {
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = malloc(sizeof(struct node)); // allocate 3 nodes in the heap
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
head->data = 1; // setup first node
head->next = second; // note: pointer assignment rule
second->data = 2; // setup second node
second->next = third;
third->data = 3; // setup third link
third->next = NULL;
// At this point, the linked list referenced by "head"
// matches the list in the drawing.
return head;
}
/*
Takes a list and a data value.
Creates a new link with the given data and pushes
it onto the front of the list.
The list is not passed in by its head pointer.
Instead the list is passed in as a "reference" pointer
to the head pointer -- this allows us
to modify the caller's memory.
*/
void Push(struct node** headRef, int data) {
struct node* newNode = malloc(sizeof(struct node));
newNode->data = data;
newNode->next = *headRef; // The '*' to dereferences back to the real head
*headRef = newNode; // ditto head points to new node
}
// Given a list and an index, return the data
// in the nth node of the list. The nodes are numbered from 0.
// Assert fails if the index is invalid (outside 0..lengh-1).
int GetNth(struct node* head, int index) {
struct node* current = head;
int answer = 0;
int x = index;
if(x <= 0 || x >= sizeof(head)-1 )
{
return -1;
}
for(int i = 0; i <= sizeof(head)-1; i++){
if (i == x){
return current->data;
}
current = current->next;
}
}
As you can see I use the BuildOneTwoThree function to build the linkedlist and am writing appropriate functions...It crashes when I try to access mylist into output.
For the most part the code seems to function from the point of view of the question only, printf had to be properly formatted.
printf("%i", length);
type cast malloc required
Change **head to *head in function argument Length
Use proper printf statement.
This question is limited to printing lenght of link list. please find code below:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* BuildOneTwoThree();
int Length(struct node* head);
int main()
{
printf("Hello world!\n");
struct node* mylist = BuildOneTwoThree();
int length = Length(mylist);
printf("data =%d\n",mylist->data);
printf("length = %d",length);
return 0;
}
// Return the number of nodes in a list (while-loop version)
int Length(struct node* head) {
int count = 0;
struct node* current = head;
while (current != NULL) {
count++;
current = current->next;
}
return(count);
}
/*
Build the list {1, 2, 3} in the heap and store
its head pointer in a local stack variable.
Returns the head pointer to the caller.
*/
struct node* BuildOneTwoThree() {
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = (struct node *)malloc(sizeof(struct node)); // allocate 3 nodes in the heap
second = (struct node *)malloc(sizeof(struct node));
third = (struct node *)malloc(sizeof(struct node));
head->data = 1; // setup first node
head->next = second; // note: pointer assignment rule
second->data = 2; // setup second node
second->next = third;
third->data = 3; // setup third link
third->next = NULL;
// At this point, the linked list referenced by "head"
// matches the list in the drawing.
return head;
}

What does each line do in this Linked List program?

Here is a linked list I am working on, and trying to figure out exactly what each line does. The way I seem to be learning how to program is painstakingly difficult, and I am getting extremely discouraged. Regardless, I understand how the link list works, but I am not understanding what the code is saying and what it exactly is doing to create the structs. For example: I can't understand why would you be assigning a pointer to node (13 and 14), especially when my understand of pointers is that they are used to store memory locations.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct numnode
{
int val;
struct numnode * next;
};
typedef struct numnode node;
main()
{
int i;
node * head;
node * newnode;
head = NULL;
for (i = 1; i <= 10; i++)
{
newnode = (node *) malloc(sizeof(node));
newnode->val = i;
newnode->next = NULL;
if (head == NULL)
{
head = newnode;
}
else
{
newnode->next = head;
head = newnode;
}
}
}
Here are some annotations (and minor edits to reduce the amount of code).
/* Linked list node definition */
struct node {
int val;
struct node * next;
};
int main() {
int i;
struct node *head, *new_node;
head = NULL;
for (i = 1; i <= 10; i++) {
// Allocate a new node and initialize its components (val and next)
new_node = (struct node *) malloc(sizeof(node));
new_node->val = i;
new_node->next = NULL;
// The if block is actually not necessary...
if (head == NULL) {
// If the linked list is empty, set the head pointer to the initial node
head = new_node;
} else {
// Now that you have your new node, connect it. Start:
// head->[current linked list]
// [new_node.next]->NULL
new_node->next = head;
// head->[current linked list]->...
// [new_node.next]->[current linked list]->...
head = newnode;
// head->[new_node.next]->[current linked list]->...
}
}
}
The key thing is that malloc returns a pointer to memory. Each new node is allocated dynamically and thus is a location in memory (not a basic type).
If you fix the statement pointed out by PakkuDon you will find that the code inserts at the head. It will end up with a list whose values descend from 9 down to 1.
pointer is just the thing to tell you where is the value,like a phone number,you can call anyone no matter who there is,as you konw the number.pointer can point to anything(under your access) as you want,no matter it is a int or a struct.
Here is the summary of this code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct numnode
{
int val;
struct numnode * next;
};
typedef struct numnode node;
main()
{
int i;
node * head;
node * newnode;
head = NULL;
for (i = 1; i <= 10; i++)
{
newnode = (node *) malloc(sizeof(node));
newnode->val = i;
newnode->next = NULL;
if (head == NULL) // It'll be NULL first time, as head = NULL.
{
// True # i = 1
head = newnode;
}
else // Afterwards, as head=newnode
{
// New node will be created every time. Till i <= 10.
newnode->next = head;
head = newnode;
}
}
}
It is a simple code though.
PS: It is head == NULL

Rotate a linked list

I want to rotate a linked list that contains a number. 123 should be rotated to 231. The function created 23 but the last character stays empty, why?
typedef struct node node;
struct node{
char digit;
node* p;
};
void rotate(node** head){
node* walk= (*head);
node* prev= (*head);
char temp= walk->digit;
while(walk->p!=NULL){
walk->digit=walk->p->digit;
walk= walk->p;
}
walk->digit=temp;
}
How I create the list:
node* convert_to_list(int num){
node * curr, * head;
int i=0,length=0;
char *arr=NULL;
head = NULL;
length =(int) log10(((double) num))+1;
arr =(char*) malloc((length)*sizeof(char)); //allocate memory
sprintf (arr, "%d" ,num); //(num, buf, 10);
for(i=length;i>=0;i--) {
curr = (node *)malloc(sizeof(node));
(curr)->digit = arr[i];
(curr)->p = head;
head = curr;
}
curr = head;
return curr;
}
Your linked list actually has 4 elements.
You should change this line:
for(i = length; i >= 0 ; i--) {
to:
for(i = length - 1; i >= 0; i--) {
because with the former line you're going out of the array (you're accessing arr[length] on the first iteration).
With this change your rotate function works correctly.
You can solve most problems by breaking them down into simpler ones.
Here, I'd write your rotate as follows:
void rotate(node **list) {
node *head = pop_head(list);
push_at_end(list, head);
}
node *pop_head(node **list) {
assert(*list);
node *head = *list;
*list = head->p;
head->p = 0;
return head;
}
void push_at_end(node **list, node *head) {
node *end = get_end(*list);
if (!end) {
*list = head;
} else {
end->p = head;
}
}
node *get_end(node *head) {
node *last = 0;
while (head) {
last = head;
head = head->p;
}
return last;
}
The problem with your question is that the list is stored backwards, and you have a pointer to previous, instead next. This should have been part of the question (it took me a while to understand that).
Actually, you use head when probably tail would have been better. You should consider storing a pointer to the actual head, and avoid this way copying. In that case, you would only need to adjust pointers. If rotation is going to be a common task, then keeping and updating an extra pointer, may be in a list struct, would pay the effort (could change the task from O(n) to O(1)).
struct _list {
node * tail;
node * head;
};
typedef struct _list list;
In any case, the problem with your rotate function is that you are starting with walk and prev at the same node, head.
void rotate(node** head){
node* walk= (*head);
node* prev=(*head)->p;
char temp= walk->digit;
while(prev!=NULL){
walk->digit=prev->digit;
walk= prev;
prev = prev->p;
}
walk->digit=temp;
}
I have written the code for linked list rotation by k nodes in c++. It worked for me perfectly. If you pass k as 1, it will rotate the liked list by 1 node and here it solves the given problem. If you want to rotate the linked list by k nodes, it will still work fine. Please find it below.
Header file :
public:
typedef struct node {
int data;
node *next;
} *Node;
Node head;
void rotateByk(int k);
Following code is for .cpp file.
void DList::rotateByk(int k){
Node current = head;
Node kthNode;
int count = 1;
while(count<=k && current!=NULL){
kthNode = current;
current = current->next;
count++;
}
Node kthNextNode = current;
while(current->next!=NULL){
current = current->next;
}
current->next = head;
head = kthNextNode;
kthNode->next = NULL;
Node printNode = head;
while(printNode!=NULL){
cout << printNode->data << "\t";
printNode = printNode->next;
}
}
Pass k as argument in main method for linked list d1.
d1.rotateByk(1);
Please let me know if you have any queries.

Resources