Node in linked-List with C language - c

I start learning linked list,so my question may be stupid :p . I noticed that in all the exercices, they only take one data element in the node( as below : int data).So i am asking can we define multiple data elements in one node.Otherwise why not?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* nextptr;
};
struct node* BuildList()
{
/* initialize node's pointers */
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
/* allocate three nodes in the heap*/
head = malloc(sizeof(struct node));
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
/* setup first node */
head->data = 1;
head->nextptr = second;
second->data = 2;
second->nextptr = third;
third->data =3;
third->nextptr = NULL;
return head;
}

Yes, int just make it easier for the examples. But in real life, the node will be something more useful. Example:
struct chair {
int nr_or_legs;
int weight_in_kg;
int height_in_cm;
};
struct chair_node {
struct chair data;
struct chair_node* nextptr;
};
or just:
struct chair_node {
int nr_or_legs;
int weight_in_kg;
int height_in_cm;
struct chair_node* nextptr;
};

Related

recursively call in c to create link list

I am new in c so any help will be appreciated. I need to print 10 numbers from a linked list (it doesnt matter which numbers for now) I believe my code will print 9,8,7...0. for example. The linked list will be part of a struct (struct data) that will contain other variables (not important for now)
//linked list
struct listOfNodes {
struct node *root;
};
//list of parameters to send to the function to print nodes
struct data {
struct listOfNodes *list;
int total;
};
I need to send the struct (struct data) as a parameter of a recursive function (addNode). In this recursive function, I need to add a new node to the linked list and call recursively 10 times to create more nodes for the link list, then I need to print the linked list. I have the following code so far
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//node
struct node {
int value;
struct node *next;
};
//linked list
struct listOfNodes {
struct node *root;
};
//list of parameters to send to the function to print nodes
struct data {
struct listOfNodes *list;
int total;
};
void printNode(struct listOfNodes *list) {
struct node *n = list->root;
while(n!=NULL){
printf("%d\n",n->value);
n=n->next;
}
}
void addNode(void* d){ //parameter needs to be a void*
struct data *o = (struct data *)d ;
if(o->total<10) {
//create new node
struct node *n = malloc(sizeof(struct node));
n->value = o->total;
n->next = NULL;
o->total = o->total + 1;
if(o->list->root == NULL)
{
o->list->root = n;
}
else {
n->next = o->list->root->next;
o->list->root->next = n;
}
addNode(d);
}
}
int main() {
struct data *d= malloc(sizeof(struct data *));
d->total=0;
d->list=NULL;
addNode(d); //add recursively 10 times
if(d->list!=NULL) printNode(d->list);
return 0;
}
But I am getting Segmentation fault (core dumped). Can you please help me?
In your main program, you added list as NULL. But in your addNode, you only check if list->root is NULL. What's happening is when
if(o->list->root == NULL)
{
o->list->root = n;
}
is accessing list->root when list is NULL. You de reference a NULL pointer and segfault.
You probably need
struct listOfNodes *variable=malloc(sizeof(struct listOfNodes));
d->list=variable;
Changes are describe in comments
#include <stdio.h>
// #include <string.h> // <------- 4 not needed.
#include <stdlib.h>
struct node {//node
int value;
struct node *next;
};
struct listOfNodes {//linked list
struct node *root;
};
struct data {//list of parameters to send to the function to print nodes
struct listOfNodes *list;
int total;
};
void printNode(struct listOfNodes *list) {
struct node *n = list->root;
while(n!=NULL){
printf("%d\n",n->value);
n=n->next;
}
}
void addNode(struct data * d){ // <------- 3 no need to be void * so o replaced by d
if(d->total<10) {
//create new node
struct node *n = malloc(sizeof(struct node));
n->value = d->total;
n->next = NULL;
d->total = d->total + 1;
if(d->list->root == NULL)
{
d->list->root = n;
}
else {
n->next = d->list->root->next;
d->list->root->next = n;
}
addNode(d);
}
}
int main() {
struct data *d= malloc(sizeof(struct data)); // <---- 1 allocate data size not pointer size.
d->total=0;
d->list = malloc(sizeof(struct listOfNodes)); // <---- 2 alocate list !
d->list->root = NULL; // <---- 2 init root.
addNode(d); //add recursively 10 times
if(d->list!=NULL) printNode(d->list);
return 0;
}

How to return pointer adress for structure variable

I was working on data structures and while I was writing some code, I needed to return the address of the pointer that was defined in the structure. So here's my code but when I compile and run it, it doesn't work and give an error message as " assignment makes pointer from integer without a cast ". How should I rewrite it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node{
int x;
struct Node *next;
};
void main(){
int i;
struct Node *head;
head = (struct Node*) malloc(sizeof(struct Node));
head->next=NULL;
/*Ekle(5,head);
Ekle(10,head);
Ekle(15,head);
printf("Enter the value of 'ara' element");
scanf("%d",&i);
Print(head);
ArayaEkle(i,20,head);
Print(head);*/
head = siraliEkle(10,head);
head = siraliEkle(5,head);
Print(head);
}
void Print(struct Node *root){
while(root->next!=NULL){
root = root->next;
printf("%d\n",root->x);
}
}
struct Node *siraliEkle(int sayi, struct Node *root){
if(root==NULL){
root = (struct Node*) malloc(sizeof(struct Node));
root->x = sayi;
root->next = NULL;
return root;
}
else if(root->next==NULL){
if(root->x>sayi){
struct Node *temp = (struct Node*) malloc(sizeof(struct Node));
temp->x = sayi;
temp->next = root;
root = temp;
return root;
}
}
}
You must declare (or define) functions before using them.
Without declaration nor definition, types of function arguments are assumed to int and it will cause trouble when actual types are not int.
struct Node{
int x;
struct Node *next;
};
/* add these declarations */
void Print(struct Node *root);
struct Node *siraliEkle(int sayi, struct Node *root);
int main(){ /* also return type should be standard int */
Also don't forget to return something from siraliEkle even if root != NULL && (root->next != NULL || root->x <= sayi).
If you want to return the address for the struct pointer use the declaration
struct Node *siraliEkle(int sayi, struct Node *root);
As below and return:
return &root;

I can not pass by reference my node

I dont want create general *head node and I want to pass by reference and chance my data but although create new node for next node I cant reach my new node on main.
İf I look n1.next in main I see it is null.Why ?What is wrong ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node{
int data;
struct node* next;
};
void add(struct node** head,int data){
struct node * tmp = *head;
while(tmp != NULL){
tmp = tmp->next;
}
tmp = (struct node*) malloc(sizeof(struct node));
tmp->data= data;
tmp->next=NULL;
}
int main()
{
struct node n1;
n1.data=5;
n1.next=NULL;
add(&(n1.next),15);
printf("%d",n1.next->data);
return 0;
}
Instead of using a head pointer, are you trying to pass in the last next pointer in the list, and then update that to point to your new node? If so, add() should be
void add(struct node** head, int data) {
struct node* p = malloc(sizeof(*p));
p->data = data;
p->next = NULL;
*head = p;
}

How to split a linked-list into two lists

I'm writing a code to split a circular linked-list to two linked lists with equal number of codes, following is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node *ptr;
struct node {
int element;
ptr prev;
ptr next;
};
typedef ptr list;
typedef ptr position;
int main() {
list L=malloc(sizeof(struct node));
list first=malloc(sizeof(struct node));
list second=malloc(sizeof(struct node));
splitlist(L,first,second);
return 0;
}
void splitlist(list L, list first,list second) {
position p,temp;
p=malloc(sizeof(struct node));
temp=malloc(sizeof(struct node));
p=L;
int count=0;
while ((p)->next != L) {
count++;
}
int c=count;
while (c!=(count/2)-1) {
p=(p)->next;
temp=(p)->next;
}
first=L;
(p)->next=NULL;
second=temp;
c=count;
while (c!=(count/2)-1) {
temp=(temp)->next;
}
(temp)->next=NULL;
}
When compiling my code it gives no errors but I'm not sure if it's working properly.
In order to get more readable and maintainable code, the first step to improve the code could be to create functions which help manipulating lists. Candidate functions are:
ListInitialize()
ListPushFront()
ListPushBack()
ListPopFront()
ListPopBack()
ListGetFirstNode()
ListGetNextNode()
ListGetFront()
ListGetBack()
ListEmpty()
...
With a proper set of arguments and return values of course.
Then you can write your splitlist function using those basic list operation functions and your code will be easier to read and to reason about.
Also, in order to handle an empty list, you should have an extra list type which is not just a pointer to a node.
typedef struct Node_tag { int value; struct Node_tag *next; struct Node_tag *prev } Node, *NodePtr;
typedef struct IntList_tag { NodePtr front; NodePtr back; } IntList;
// Creates an empty list.
void ListInitialize( IntList *pList ) { pList->front = NULL; pList->back = NULL; }
void ListPushFront( IntList *pList, int value )
{ NodePtr newNode = malloc(sizeof(Node));
if(NULL != newNode )
{ newNode->next = pList->front;
newNode->prev = NULL; newNode->value = value;
pList->front = newNode;
if( pList->back == NULL ) pList->back = newNode; // first element...
}
}
// ...
Eventually, using those functions, you can write splitlist() function in a concise and noise-free way:
void splitlist( IntList * source, IntList *target1, IntList *target2 )
{
IntList * currentTarget = target1;
for( NodePtr currentNode = ListGetFirstNode(source); currentNode != NULL; currentNode = ListGetNextNode(currentNode) )
{
ListPushBack(currentTarget, currentNode->value );
if(currentTarget == target1 ) currentTarget = target2;
else currentTarget = target1;
}
}
It might appear that it is much work to create all those other list functions if all you want is splitlist. But in real world applications you will most likely want all those other functions as well (or you have them already). Only in homework situations, this looks a bit funny.
Example code. Using typedef for node to be compatible with Microsoft C compilers (C89). Note sometimes the pointer to a circular list is a pointer to the last node of the circular list, (which contains a pointer to the first node of the circular list), allowing for faster appends. This example assumes list pointers are pointers to first nodes, but could be modified to assume list pointers are to last nodes.
#include <stdlib.h>
typedef struct _node{
struct _node *next;
int data;
}node;
node * splitlist(node * psrc, node ** ppdst1, node ** ppdst2)
{
node *ps = psrc;
node ** ppd1 = ppdst1;
node ** ppd2 = ppdst2;
*ppd1 = *ppd2 = NULL;
if(ps == NULL)
return NULL;
while(1){
*ppd1 = ps;
ps = *(ppd1 = &(ps->next));
if(ps == psrc)
break;
*ppd2 = ps;
ps = *(ppd2 = &(ps->next));
if(ps == psrc)
break;
}
*ppd1 = *ppdst1;
*ppd2 = *ppdst2;
return NULL;
}
main()
{
node a[8] = {{&a[1],0},{&a[2],1},{&a[3],2},{&a[4],3},
{&a[5],4},{&a[6],5},{&a[7],6},{&a[0],7}};
node *pa = &a[0];
node *pb = NULL;
node *pc = NULL;
pa = splitlist(pa, &pb, &pc);
return 0;
}

New with nodes in C, how to fix the struct?

I have problems with understanding the whole concept of this. The major issue that confuses me is the the pointer inside a struct inside a struct... Basically what I understand is that I am wanting to create a chain of nodes.
When I run this program it crashes after two seconds. I believe there is something wrong with my structure in main.c, because I have created it by myself and as you can see I am really Bambi on thin ice over here...
main.c
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "list.h"
// I guess my struct is not correct
static struct {
LIST node;
int item;
} node;
int main() {
list_create();
list_append(node.node, node.item);
}
list.h
typedef struct node* LIST;
LIST list_create (void);
void list_append (LIST l, int item);
list.c
struct node* list_create() {
struct node* head = (struct node*) malloc(sizeof (struct node));
head->next = NULL;
return head;
}
void list_append(struct node* n, int item)
{
/* Create new node */
struct node* new_node = (struct node*) malloc (sizeof (struct node));
new_node->item = item;
/* Find last link */
while (n->next) {
n = n->next;
}
/* Joint the new node */
new_node->next = NULL;
n->next = new_node;
}
At first, node is use for create a structure with data and in THIS data you have a pointer to another struct.
static struct {
LIST node;
int item;
} node;
Actually your structure is incorrect.
You must create at beginning a structure with your data for example :
static struct node{
int item;
};
then put a pointer to the similar structure but will not have same data =>
static struct node{
struct node *next;
int item;
};
You will can use this pointer to manipulate other & other structure.
I see another problem in your main :
You call the function "list_create()" which return a pointer to structure but you assign nothing.
you must create a pointer to struct then assign it like this :
int main() {
struct node *list;
list = list_create();
}
This code works completely (you can put it all in one C file; annotations in the code):
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
/* I removed the "static", because what we want is a type,
not a global static variable */
/* This "node" is our list-element. It has a pointer to a next element, and
some data, in this case, an int. */
typedef struct node {
struct node *next;
int item;
} node;
/* For convenience, another type, a pointer to a node. */
typedef node *LIST;
/* Creating a list is as simple as creating a node, and make the "next"
pointer NULL, you got this correct. */
struct node* list_create() {
struct node* head = (struct node*) malloc(sizeof (struct node));
head->next = NULL;
return head;
}
/* Nothing wrong in this append code. */
void list_append(struct node* n, int item)
{
/* Create new node */
struct node* new_node = (struct node*) malloc (sizeof (struct node));
new_node->item = item;
/* Find last link */
while (n->next) {
n = n->next;
}
/* Joint the new node */
new_node->next = NULL;
n->next = new_node;
}
/* I added this to make sure it works :) */
void print_list(LIST l) {
LIST tmp = l;
while (tmp) {
printf("%d\n", tmp->item);
tmp = tmp->next;
}
/* Here are some changes. I create a local LIST (which is basically a pointer
to a node, remember?) and use list_create to initialise it. Then, I call
list_append two times to put some extra data into it.
Works perfectly! */
int main() {
LIST myList = list_create();
list_append(myList, 10);
list_append(myList, 13);
print_list(myList);
}
You are calling list_create, but not using its result.

Resources