How to make to linked list in C? - c

Using two linked lists or something similar, I want to add "ABCD", then I want to get "ABDC".
I'm not sure if my code is right, I'm a noob in C.
The code should have pointer and malloc. I made it like this:
struct Node
{
char data;
struct Node* next;
};
struct Node* newNode(char data)
{
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->next = NULL;
return node;
}
struct Node* constructList()
{
struct Node* first = newNode(1);
struct Node* second = newNode(2);
struct Node* third = newNode(3);
struct Node* forth = newNode(4);
struct Node* head = first;
first->next = second;
second->next = third;
third->next=forth;
return head;
}
void printList(struct Node* head)
{
struct Node* ptr = head;
while (ptr)
{
printf("%d -> ", ptr->data);
ptr = ptr->next;
}
printf("NULL");
}

Your code is fine as shown, though it lacks error handling (and why are you using char to store integers?).
Do make sure you free() the nodes when you are done using them, eg:
void freeList(struct Node* head)
{
struct Node* ptr = head;
struct Node* next;
while (ptr)
{
next = ptr->next;
free(ptr);
ptr = next;
}
}
I would suggest changing constructList() to use a loop, eg:
struct Node* constructList()
{
struct Node *head = NULL;
struct Node **ptr = &head;
for (int value = 1; value <= 4; ++value)
{
*ptr = newNode(value);
if (*ptr == NULL)
{
freeList(head);
return NULL;
}
ptr = &((*ptr)->next);
}
return head;
}
You could then generalize constructList() to take an array of integers, or a string, as input and loop through that input adding a new node for each value. For example, try this:
struct Node
{
char data;
struct Node* next;
};
struct Node* newNode(char data)
{
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
if (node)
{
node->data = data;
node->next = NULL;
}
return node;
}
void freeList(struct Node* head)
{
struct Node* ptr = head;
struct Node* next;
while (ptr)
{
next = ptr->next;
free(ptr);
ptr = next;
}
}
struct Node* constructList(const char *str)
{
struct Node *head = NULL;
struct Node **ptr = &head;
char ch;
if (str)
{
while ((ch = *str++) != '\0')
{
*ptr = newNode(ch);
if (*ptr == NULL)
{
freeList(head);
return NULL;
}
ptr = &((*ptr)->next);
}
}
return head;
}
void printList(struct Node* head)
{
struct Node* ptr = head;
while (ptr)
{
printf("%c -> ", ptr->data);
ptr = ptr->next;
}
printf("NULL");
}
struct Node *list = constructList("ABCD");
printList(list);
freeList(list);

Related

How to use the variable globally in the function

I am writing a C code to insert an element to a sorted linked list. In this code I am using the variable "place" for deciding the position to insert the new element. But here it is getting error that "place" variable is to declared first. But I need the place globally for using in other functions. So what can I do to make it work? Also there is some problem with the function calling in the last part of main function. Please help me to correct it. Please let me know if there are any other errors. Thank You
#include<stdio.h>
#include<stdlib.h>
struct Node{
int data;
struct Node *next;
};
int calcSize(struct Node* node){
int size=0;
while(node!=NULL){
node = node->next;
size++;
}
return size;
}
void insertPosition(int pos, int data, struct Node** head)
{
int size = calcSize(*head);
if(pos < 1 || size < pos)
{
printf("Can't insert, %d is not a valid position\n",pos);
}
else
{
struct Node* temp = *head;
struct Node* newNode = (struct Node*)
malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
while(--pos)
{
temp=temp->next;
}
newNode->next= temp->next;
temp->next = newNode;
}
}
void insertStart(struct Node** head, int data){
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
void insertLast(struct Node** head, int data){
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
if(*head==NULL){
*head = newNode;
return;
}
struct Node* temp = *head;
while(temp->next!=NULL)
temp = temp->next;
temp->next = newNode;
}
void display(struct Node* node){
while(node!=NULL){
printf("%d ",node->data);
node = node->next;
}
printf("\n");
}
void check(struct Node* node,int ele){
while(node!=NULL){
int i=0;
if(ele>node->data)
{ place=i; break;}
node= node->next;
}
}
int main()
{ int ele; int place=0;
struct Node* head = NULL;
struct Node* node2 = NULL;
struct Node* node3 = NULL;
struct Node* node4 = NULL;
struct Node* node5 = NULL;
head = (struct Node*)malloc(sizeof(struct Node));
node2 = (struct Node*)malloc(sizeof(struct Node));
node3 = (struct Node*)malloc(sizeof(struct Node));
node4 = (struct Node*)malloc(sizeof(struct Node));
node5 = (struct Node*)malloc(sizeof(struct Node));
head->data = 5; head->next = node2;
node2->data = 10; node2->next = node3;
node3->data = 18; node3->next = node4;
node4->data = 26; node4->next = node5;
node5->data = 32; node5->next = NULL;
printf("Current Items in Linked List\n");
display(head);
printf("Enter the element to insert into LL\n");
scanf("%d",&ele);
printf("Inserting into Linked List....");
if(place=1)
{ void insertStart(&head, ele); }
else if(place=5)
{ void insertLast(&head, ele); }
else
{ void insertPosition(place, ele, &head); }
return 0;
}

linked list implemetation from scratch, segmentation fault

I want to implement linked list from scratch. I programmed it, but when I run it gives me a Segmentation fault in my node_adder(int data) function. I don't know what caused this.
struct linked_list
{
int value;
struct linked_list *next;
};
struct linked_list *head = NULL;
struct linked_list *tail = NULL;
void node_adder(int data)
{
struct linked_list *new = NULL;
new->value = data;
new->next = NULL;
if (head == NULL)
{
head = new;
tail = new;
printf("head added\n");
}
else
{
tail->next = new;
tail = new;
printf("tail added\n");
}
}
In node_adder(), you are not allocating any memory for the new node before accessing its members.
Try this instead:
struct linked_list
{
int value;
struct linked_list *next;
};
struct linked_list *head = NULL;
struct linked_list *tail = NULL;
void node_adder(int data)
{
struct linked_list *newNode;
// ADD THIS!!!
// in C:
newNode = malloc(sizeof(struct linked_list));
// in C++:
newNode = new linked_list;
//
newNode->value = data;
newNode->next = NULL;
if (head == NULL)
{
head = tail = newNode;
printf("head added\n");
}
else
{
tail->next = newNode;
tail = newNode;
printf("tail added\n");
}
}
This line initializes a pointer to a node to NULL:
struct linked_list *new = NULL;
Yet, no memory is allocated for this node. Therefore, in this line, attempting to assign a value to one of the members of the node leads to a segmentation fault:
new->value = data;
You probably meant to do this:
struct linked_list *new = malloc(sizeof(struct linked_list));
Of course, a corresponding free(..) should also be added when the allocated memory will no longer be used.
For starters it is a bad idea to declare global variables and define functions that depend on the global variables as you are doing
struct linked_list *head = NULL;
struct linked_list *tail = NULL;
because in this case you will not be able to define for example more than one list.
It is much better to introduce one more structure like for example
struct node
{
int value;
struct node *next;
};
struct linked_list
{
struct node *head;
struct node *tail;
};
As for your problem then you are using a null pointer to access memory that results in undefined behavior
void node_adder(int data)
{
struct linked_list *new = NULL;
new->value = data;
new->next = NULL;
//...
You need to allocate a node dynamically as for example
int node_adder(int data)
{
struct linked_list *new = malloc( sizeof( *new ) );
int success = new != NULL;
if ( success )
{
new->value = data;
new->next = NULL;
if (head == NULL)
{
head = new;
}
else
{
tail->next = new;
}
tail = new;
}
return success;
}
But using the approach I showed in the beginning of my answer You could write instead
struct node
{
int value;
struct node *next;
};
struct linked_list
{
struct node *head;
struct node *tail;
};
int node_adder( struct linked_list *list, int data )
{
struct node *new = malloc( sizeof( *new ) );
int success = new != NULL;
if ( success )
{
new->value = data;
new->next = NULL;
if (list->head == NULL)
{
list->head = new;
}
else
{
list->tail->next = new;
}
list->tail = new;
}
return success;
}
and in main you can write
int main( void )
{
struct linked_list list = { .head = NULL, .tail = NULL };
node_adder( &list, 10 );
//...
}

What is the problem with this piece of code?

I am writing for deleting the last node of a doubly linked list. But, every time this function is giving me segmentation fault when I have 2 or more than 2 elements in the list.
void deleteEnd()
{
struct node *ptr;
if(head==NULL)
printf("\nList is empty.First add some numbers");
else if(head->next==NULL)
{
head = NULL;
free(head);
}
else
{
ptr = head;
while(ptr->next != NULL)
{
ptr = ptr -> next;
}
ptr -> prev -> next = NULL;
free(ptr);
}
}
Normally, when you are deleting a node from a linked list it is a good practice to pass a reference to the first node of the list as an argument of the function. In your case you are not showing us where the head is coming from, and I think that it could be quite a useful info, and I bet that the error hides there.
That is how the implementation could look like:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
// insert end node: this is for testing purposes
struct node *insertEnd(struct node *head, int value) {
struct node *ptr, *new_node;
ptr = head;
new_node = (struct node *) malloc(sizeof(struct node));
new_node->data = value;
new_node->next = NULL;
// The list is empty
if (head == NULL) {
head = new_node;
return head;
}
// Non empty list
while (ptr->next != NULL) {
ptr = ptr->next;
}
ptr->next = new_node;
return head;
}
// delete end node
struct node *deleteEnd(struct node *head) {
struct node *ptr, *preptr;
ptr = head;
preptr = NULL;
// The list is empty
if (head == NULL) {
printf("The list is empty. Nothing to delete.\n");
return head;
}
while(ptr->next != NULL) {
preptr = ptr;
ptr= ptr->next;
}
free(ptr);
if (preptr == NULL) {
head = NULL;
}
else {
preptr->next = NULL;
}
return head;
}
int main(void) {
struct node *llist;
llist = NULL;
llist = insertEnd(llist, 10);
llist = insertEnd(llist, 20);
llist = insertEnd(llist, 30);
llist = deleteEnd(llist);
llist = deleteEnd(llist);
llist = deleteEnd(llist);
return 0;
}
It is always a great idea to maintain a global variable head and update it after every push/pop. See this:
struct node
{
int data;
struct node *next;
};
struct node *start = NULL;
struct node *deleteEnd(struct node *start)
{
struct node *ptr = start;
if(ptr==NULL)
{
printf("\nList is empty!!!");
return start;
}
else if(ptr->next == NULL)
{
free(ptr);
start = NULL;
return start;
}
else
{
while((ptr->next)->next!=NULL) //by doing this you dont have to maintain a prev pointer
{
ptr=ptr->next;
}
struct node *temp = ptr->next;
free(temp);
ptr->next = NULL;
return start;
}
}
Hope this helps!!!

linked list c programming error by inserting new element

I am trying to insert an element but it get the error "Process finished with exit code 11"
struct node {
int key;
struct node *next;
};
struct node* init(){
struct node *head =NULL;
return head;
}
void create(struct node * head,int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while(tmp!= NULL && tmp->key < num){
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp== NULL)
head=tmp;
}
int main() {
int num;
struct node* head;
head=init()
printf("Enter data:");
scanf("%d",&num);
create(head,num);
}
i am trying to insert an element into a linked list and the element should be sorted and entered at the same time.can someone tell me that the error is ? i cannot seem to find out the error.
It's not clear what your function create()
void create(struct node * head, int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while (tmp != NULL && tmp->key < num) {
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp == NULL)
head = tmp;
}
is supposed to do. You effectively pass it a NULL pointer and return void, so everything it does is meaningless to the outside world.
Thetm starting point for every no bs linked list implementation:
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct node_tag {
int value;
struct node_tag *next;
} node_t;
// write functions to encapsulate the data and provide a stable interface:
node_t* node_create_value(int value)
{
node_t *new_node = calloc(1, sizeof *new_node);
if(new_node) new_node->value = value;
return new_node;
}
node_t* node_advance(node_t const *node) { return node->next; }
typedef struct list_tag { // a list usually consists of
node_t *head; // a pointer to the first and
node_t *tail; // a pointer to the last element
// size_t size; // one might want to add that.
} list_t;
list_t list_create(void)
{
list_t list = { NULL, NULL };
return list;
}
// make code based on these functions "speak" for itself:
node_t* list_begin(list_t const *list) { return list->head; }
node_t* list_end (list_t const *list) { return list->tail; }
bool list_is_empty(list_t const *list) { return !list_begin(list); }
// common operations for lists:
node_t* list_push_front(list_t *list, int value)
{
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = list->head;
return list->head = new_node;
}
node_t* list_push_back(list_t *list, int value)
{
// push_back on an empty list is push_front:
if (list_is_empty(list))
return list->tail = list_push_front(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
list->tail->next = new_node;
return list->tail = new_node;
}
node_t* list_insert_after(list_t *list, node_t *node, int value)
{
if (list_end(list) == node)
return list_push_back(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = node->next;
return node->next = new_node;
}
node_t* list_insert_sorted(list_t *list, int value)
{
// first handle the special cases that don't require iterating the whole list:
if (list_is_empty(list) || value < list_begin(list)->value)
return list_push_front(list, value);
if (value > list_end(list)->value)
return list_push_back(list, value);
// the general (worst) case:
for (node_t *current_node = list_begin(list); node_advance(current_node); current_node = node_advance(current_node))
if (value < node_advance(current_node)->value)
return list_insert_after(list, current_node, value);
return NULL; // should never happen
}
void list_print(list_t const *list)
{
for (node_t *current_node = list_begin(list); current_node; current_node = node_advance(current_node))
printf("%d\n", current_node->value);
}
void list_free(list_t *list)
{
for(node_t *current_node = list_begin(list), *next_node; current_node; current_node = next_node) {
next_node = current_node->next;
free(current_node);
}
}
// user code should not be required to know anything about the inner workings
// of our list:
int main(void)
{
list_t list = list_create();
for (int i = 1; i < 10; i += 2) {
if (!list_push_back(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
putchar('\n');
for (int i = 0; i < 11; i += 2) {
if (!list_insert_sorted(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
list_free(&list);
}
Output:
1
3
5
7
9
0
1
2
3
4
5
6
7
8
9
10

Code to insert node at last position in C programming language

I am writing a code on linklist in C programming language. When I am using an online compiler my code is working fine but when I am using Codeblock to run the code, the code is not working. I am posting the code kindly provide me solution. My code is to add node in a linklist on the last position.
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node* Head;
void insert(int);
void print();
int main()
{
Head = NULL;
insert(2);
insert(3);
insert(4);
print();
return 0;
}
void insert(int a)
{
struct Node* temp1=(struct Node*)malloc(sizeof(struct Node));
temp1-> data = a;
temp1-> next = NULL;
if(Head == NULL)
{
Head = temp1;
return;
}
struct Node* temp = Head;
while(temp->next!= NULL)
{
temp = temp->next;
}
temp-> next = temp1;
}
void print()
{
struct Node* temp2=Head;
while(temp2 != NULL)
{
printf("%d \n", temp2->data);
temp2 = temp2->next;
}
return;
}
Here is how you can achieve what you want to do.
I suggest you to use a top-down approach when programming.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int info;
struct node *next;
};
struct node *Insert(struct node *, int);
void Print_List(struct node *);
void Remove_List(struct node *);
int main(int argc, char **argv)
{
struct node *head;
head = NULL;
head = Insert(head, 10);
head = Insert(head, 20);
Print_List(head);
Remove_List(head);
head = NULL;
return 0;
}
struct node *Create_New_Node(int);
struct node *Head_Insert(struct node *, int);
struct node *Queue_Insert(struct node *, int);
struct node *Insert(struct node *, int);
void Print_List(struct node *);
void Remove_List(struct node *);
struct node *Insert(struct node *top, int elem)
{
if(top == NULL)
{
top = Head_Insert(top, elem);
}
else
{
top = Queue_Insert(top, elem);
}
return top;
}
struct node *Create_New_Node(int elem)
{
struct node *new_node;
new_node = (struct node *)malloc(sizeof(struct node));
if(new_node != NULL)
{
new_node -> info = elem;
new_node -> next = NULL;
}
return new_node;
}
struct node *Head_Insert(struct node *top, int elem)
{
struct node *new_node = Create_New_Node(elem);
if(new_node != NULL)
{
new_node -> next = top;
}
return new_node;
}
struct node *Queue_Insert(struct node *top, int elem)
{
if(top != NULL)
{
if(top -> next != NULL)
{
top -> next = Queue_Insert(top -> next, elem);
}
else
{
struct node *new_node = Create_New_Node(elem);
if(new_node != NULL)
{
top -> next = new_node;
}
}
}
return top;
}
void Print_List(struct node *top)
{
while(top != NULL)
{
printf("\nInfo : %d\tAddress : %u\tNext link address : %u\n", top -> info, top, top -> next);
top = top -> next;
}
return;
}
void Remove_List(struct node *top)
{
if(top != NULL)
{
Remove_List(top -> next);
top -> next = NULL;
free(top);
}
return;
}
Sample output :
Info : 10 Address : 39149584 Next link address : 39149616
Info : 20 Address : 39149616 Next link address : 0

Resources