I am trying to implement a linked list in C:
struct Node{
struct Node *next;
void *data;
};
With an insert function:
void insert(void *p2Node, void *data)
{
struct Node *newNode;
struct Node **p2p2Node= (struct Node **)p2Node;
if (newNode = malloc(sizeof(struct Node))) /* if successfully allocated */
{
newNode->data = data;
if ((*p2p2Node) != NULL) /* if the list is not empty */
{
newNode->next = (*p2p2Node)->next;
(*p2p2Node)->next = newNode;
}
else
(*p2p2Node) = newNode;
p2Node = p2p2Node;
}
printf("Inside the insert: %s\n", (*p2p2Node)->data);
}
I called insert in main():
int main()
{
char *setA = "liquid ";
char *setB = " lgd";
char *setC = "sample";
struct Node *nList = malloc(sizeof(struct Node));
insert(nList, setC);
printf("2Get %s\n", nList->data);
return 0;
}
No error or warning was reported, but the value was only changed inside the insert. Back to main() the linked list is still empty.
I do not understand: nList in main() is a void pointer. Inside insert(), *p2Node is not altered, I used p2p2Node to change the value p2Node points to, why is it not working? Did I mismatch the pointers? Is there a way I can make it work without modifying the parameter of insert()?
Thank you.
Use this code to insert values to the linked list.
struct node{
int data;
struct node* link;
};
struct node *root = NULL;
int len;
int main()
{
append();
display();
addatbegin();
display();
addatafter();
display();
}
Add values to the end of the list.
void append(){
struct node* temp;
temp = (struct node*)malloc(sizeof(struct node));
printf("Enter the data: ");
scanf("%d", &temp->data);
temp->link = NULL;
if(root == NULL) //list is empty
{
root=temp;
}else
{
struct node* p;
p=root;
while(p->link != NULL)
{
p = p->link;
}
p->link = temp;
}
}
Add values to the beginning of the list.
void addatbegin()
{
struct node* temp;
temp = (struct node*)malloc(sizeof(struct node));
printf("Enter the data : ");
scanf("%d", &temp->data);
temp->link = NULL;
if(root == NULL)
{
temp = root;
}
else
{
temp->link = root;
root = temp;
}
}
Add value after a node
void addatafter()
{
struct node* temp, *p;
int loc, i=1;
printf("Enter the location : ");
scanf("%d", &loc);
if(loc > len)
{
printf("Invalid input.");
}
else
{
p = root;
while(i > loc)
{
p = p->link;
i++;
}
temp = (struct node*)malloc(sizeof(struct node));
printf("Enter the data : ");
scanf("%d", &temp->data);
temp->link = NULL;
temp->link = p->link;
p->link = temp;
}
}
To display the linked list
void display(){
struct node* temp;
temp = root;
if(temp == NULL)
{
printf("List id empty.\n");
}
else
{
while (temp != NULL){
printf("%d -> ", temp->data);
temp = temp->link;
}
printf("\n\n");
}
}
Related
The insert seems to go smoothly but the display only shows the head element only. I wanted to do this on my own and tried to use the logic. I am confused whether the fault lies in the Insert function or the Display.
I am not really that great at programming and just started learning C++.Thank you for your help.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *prev;
struct node *next;
};
struct node *head = NULL;
void insert(struct node **head)
{
struct node *newnode = (struct node *)malloc(sizeof(struct node));
newnode->next = NULL;
newnode->prev = NULL;
if ((*head) == NULL)
{
int x;
printf("\nEnter the value of the starting node :");
scanf("%d", &x);
newnode->data = x;
(*head) = newnode;
}
else
{
int pos, x;
printf("\nEnter the pos ");
scanf("%d", &pos);
if (pos == 0)
{
newnode->next = (*head);
newnode->prev = NULL;
(*head)->prev = newnode;
(*head) = newnode;
printf("\nEnter data in %d pos : ", pos);
scanf("%d", &x);
newnode->data = x;
}
else
{
struct node *temp;
struct node *ptr = (*head);
while(ptr->next!=NULL)
{
for (int i = 0; i < pos - 1; i++)
{ ptr = ptr->next;}
}
if (ptr->next == NULL)
{
newnode->prev = ptr;
newnode->next = NULL;
printf("\nEnter data in %d pos : ", pos);
scanf("%d", &x);
newnode->data = x;
}
else
{
printf("\nEnter data in %d pos : ", pos);
scanf("%d", &x);
newnode->data = x;
temp = ptr->next;
newnode->prev = ptr;
newnode->next = temp;
ptr->next = newnode;
temp->prev = newnode;
}
}
}
}
void delete (struct node **head)
{
struct node *ptr;
ptr = (*head);
if ((*head) == NULL)
{
printf("\nUnderflow\n");
}
else
{
int pos;
printf("\nEnter the pos ");
scanf("%d", &pos);
struct node *temp;
for (int i = 0; i < pos; i++)
{
ptr = ptr->next;
}
temp = ptr->next;
temp->prev = ptr->prev;
ptr->next = NULL;
ptr->prev = NULL;
}
}
void display(struct node **head)
{
struct node *ptr = (*head);
if (ptr != NULL)
{
printf(" %d ",ptr->data);
}
else
{
printf("\nUnderflow OR empty\n");
}
}
int main()
{
while (1)
{
int x;
printf("\n1.Insert\n2.Delete\n3.Display\n4.Exit\n\nChoose option :\n");
scanf("%d", &x);
switch (x)
{
case 1:
{
insert(&head);
break;
}
case 2:
{
delete (&head);
break;
}
case 3:
{
display(&head);
break;
}
default:
{
printf("\nWrong operation.Select again :");
continue;
}
}
}
return 0;
}
The display was supposed to show the list like
a-> b -> c......
In the display function you should take the next node and print that too
// head->next1->next2->NULL
struct node *ptr = (*head);
while (ptr != NULL) {
printf("%d->", ptr->data);
ptr = ptr->next;
}
printf("NULL");
I want my code to display the original input 3 -> 2-> 1-> and not display the reversed one.
The output is displaying the 1-> 2-> 3-> . I want to see the original input without ruining the codes. How can I do that? Our professor taught us the concept of linked list and it is connected in this program to input a number and check if it is a palendrome
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
void insertNum(struct node** head, int number) {
struct node* temp = malloc(sizeof(struct node));
temp -> data = number;
temp -> next = *head;
*head = temp;
}
void display(struct node* head) {
struct node* printNode = head;
printf("displaying list1...\n");
printf("displaying the converted list..\n");
while (printNode != NULL) {
if (printNode->next)
printf("%d->",printNode->data);
else
printf("%d->NULL\n",printNode->data);
printNode=printNode->next;
}
}
struct node* reverseLL(struct node* head) {
struct node* reverseNode = NULL, *temp;
if (head == NULL) {
printf("\nThe list is empty.\n\n");
exit(0);
}
while (head != NULL) {
temp = (struct node*) malloc(sizeof(struct node));
temp -> data = head -> data;
temp -> next = reverseNode;
reverseNode = temp;
head = head -> next;
}
return reverseNode;
}
int check(struct node* LLOne, struct node* LLTwo) {
while (LLOne != NULL && LLTwo != NULL) {
if (LLOne->data != LLTwo->data)
return 0;
LLOne = LLOne->next;
LLTwo = LLTwo->next;
}
return (LLOne == NULL && LLTwo == NULL);
}
void deleteList(struct node** display) {
struct node* temp = *display;
while (temp != NULL) {
temp = temp->next;
free(*display);
*display = temp;
}
}
int main() {
int inputNum, countRun = 0, loop;
char choice;
struct node* reverseList;
struct node* head = NULL;
do {
printf("%Run number : %d\n", ++countRun);
printf("Enter 0 to stop building the list, else enter any integer\n");
printf("Enter list to check whether it is a palindrome... \n");
do {
scanf("%d", &inputNum);
if (inputNum == 0)
break;
insertNum(&head, inputNum);
} while (inputNum != 0);
display(head);
reverseList = reverseLL(head);
if ((check(head, reverseList)) == 1)
printf("\nPalindrome list.\n\n");
else
printf("\nNot palindrome.\n\n");
deleteList(&head);
} while (countRun != 2);
system("pause");
return 0;
}
Your insertNum inserts at the front of the list.
You need a version that appends at the back of the list:
void
appendNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
struct node *cur;
struct node *prev;
temp->data = number;
// find tail of the list
prev = NULL;
for (cur = *head; cur != NULL; cur = cur->next)
prev = cur;
// append after the tail
if (prev != NULL)
prev->next = temp;
// insert at front (first time only)
else
*head = temp;
}
Here is the full code:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
void
appendNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
struct node *cur;
struct node *prev;
temp->data = number;
// find tail of the list
prev = NULL;
for (cur = *head; cur != NULL; cur = cur->next)
prev = cur;
// append after the tail
if (prev != NULL)
prev->next = temp;
// insert at front (first time only)
else
*head = temp;
}
void
insertNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
temp->data = number;
temp->next = *head;
*head = temp;
}
void
display(struct node *head)
{
struct node *printNode = head;
printf("displaying list1...\n");
printf("displaying the converted list..\n");
while (printNode != NULL) {
if (printNode->next)
printf("%d->", printNode->data);
else
printf("%d->NULL\n", printNode->data);
printNode = printNode->next;
}
}
struct node *
reverseLL(struct node *head)
{
struct node *reverseNode = NULL,
*temp;
if (head == NULL) {
printf("\nThe list is empty.\n\n");
exit(0);
}
while (head != NULL) {
temp = (struct node *) malloc(sizeof(struct node));
temp->data = head->data;
temp->next = reverseNode;
reverseNode = temp;
head = head->next;
}
return reverseNode;
}
int
check(struct node *LLOne, struct node *LLTwo)
{
while (LLOne != NULL && LLTwo != NULL) {
if (LLOne->data != LLTwo->data)
return 0;
LLOne = LLOne->next;
LLTwo = LLTwo->next;
}
return (LLOne == NULL && LLTwo == NULL);
}
void
deleteList(struct node **display)
{
struct node *temp = *display;
while (temp != NULL) {
temp = temp->next;
free(*display);
*display = temp;
}
}
int
main()
{
int inputNum, countRun = 0, loop;
char choice;
struct node *reverseList;
struct node *head = NULL;
do {
printf("%Run number : %d\n", ++countRun);
printf("Enter 0 to stop building the list, else enter any integer\n");
printf("Enter list to check whether it is a palindrome... \n");
do {
scanf("%d", &inputNum);
if (inputNum == 0)
break;
#if 0
insertNum(&head, inputNum);
#else
appendNum(&head, inputNum);
#endif
} while (inputNum != 0);
display(head);
reverseList = reverseLL(head);
if ((check(head, reverseList)) == 1)
printf("\nPalindrome list.\n\n");
else
printf("\nNot palindrome.\n\n");
deleteList(&head);
} while (countRun != 2);
system("pause");
return 0;
}
I'm trying to do a program that inserts and deletes students from a linked list and when I try to insert a student at the end of the list but it doesn't work. I'm pretty sur that I the function algorithm is right, but still. Anyways, here's the code:
void InsetEnd(){
stud *temp, *newnode;
char n[15];
int a;
printf("Student: \n");
printf("Name: ");
scanf("%s", n);
printf("Age: ");
scanf("%d", &a);
strcpy(newnode->name, n);
newnode->age=a;
temp=head;
while(temp!=NULL){
temp=temp->next;
}
temp = (stud *) malloc (sizeof(stud));
newnode->next = NULL;
temp->next = newnode; }
For starters the pointer newnode has indeterminate value. Thus these statements
strcpy(newnode->name, n);
newnode->age=a;
result in undefined behavior.
This loop
while(temp!=NULL){
temp=temp->next;
}
does not make sense because it is evident that after the loop the pointer temp will be equal to NULL.
And you have to change the last pointer in the list after which the new node is inserted.
The function can look at least the following way (though using the function scanf with a character array as it is used in your program is unsafe)
void InsetEnd()
{
stud *newnode;
stud **temp;
char n[15];
int a;
printf("Student: \n");
printf("Name: ");
scanf("%s", n);
printf("Age: ");
scanf("%d", &a);
newnode = ( stud * )malloc( sizeof( stud ) );
strcpy( newnode->name, n );
newnode->age = a;
newnode->next = NULL;
temp = &head;
while ( *temp != NULL ) temp = &( *temp )->next;
*temp = newnode;
}
I was able to solve the problem. It was just the allocation place in the function. I actually had to allocate memory before creating the node, which if you inverse it will not create anything and it will only display garbage.
void InsetEnd(){
stud *temp, *newnode;
char n[15];
int a;
printf("Student: \n");
printf("Name: ");
scanf("%s", n);
printf("Age: ");
scanf("%d", &a);
newnode = (stud *) malloc (sizeof(stud));
strcpy(newnode->name, n);
newnode->age=a;
temp=head;
while(temp->next!=NULL){
temp=temp->next;
}
newnode->next = NULL;
temp->next = newnode; }
Seems like you caught your own issue. Allocating memory before trying to access or set data is essential! There are a few more things I felt like I need to mention to help you in the future.
void InsetEnd(stud *head) { // pass head pointer, becomes local pointer so its not overriden
if (!head)
return; // dont do anything if list does not exist
stud *newnode; // no need for tmp anymore
char n[15] = ""; // initialize
int a;
printf("Student: \n");
printf("Name: ");
scanf("%14s", n); // take only 14 chars, leaving the 15th '\0' or you'll have problems reading long names after
printf("Age: ");
scanf("%d", &a);
newnode = calloc(1,sizeof(*newnode)); // use calloc to avoid junk
// ^ type casting a return of void* is not necessary in c
strcpy(newnode->name, n);
newnode->age=a;
while(head->next) // NULL is pretty much false
head=head->next;
// no need to set newnode next to null, its already null from calloc
head->next = newnode;
}
Hope this helps!
I will try to explain it from the following example
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
class Node {
public:
double data; // data
Node* next; // pointer
};
class List {
public:
List(void) { head = NULL; } // constructor
~List(void); // destructor
bool IsEmpty() { return head == NULL; } //boş kontrolü
Node* InsertNode(int index, double x); //node ekle
int FindNode(double x); //node bul
int DeleteNode(double x); //node sil
void DisplayList(void); //liste görüntüle
private:
Node* head; //baş kısmı
};
Node* List::InsertNode(int index, double x) {
if (index < 0) return NULL;
int currIndex = 1;
Node* currNode = head;
while (currNode && index > currIndex) {
currNode = currNode->next;
currIndex++;
}
if (index > 0 && currNode == NULL) return NULL;
Node* newNode = new Node;
newNode->data = x;
if (index == 0) {
newNode->next = head;
head = newNode;
}
else{
newNode->next = currNode->next;
currNode->next = newNode;
}
return newNode;
}
int List::FindNode(double x) {
Node* currNode = head;
int currIndex = 1;
while (currNode && currNode->data != x) {
currNode = currNode->next;
currIndex++;
}
if (currNode) return currIndex;
return 0;
}
int List::DeleteNode(double x) {
Node* prevNode = NULL;
Node* currNode = head;
int currIndex = 1;
while (currNode && currNode->data != x) {
prevNode = currNode;
currNode = currNode->next;
currIndex++;
}
if (currNode) {
if (prevNode) {
prevNode->next = currNode->next;
delete currNode;
}
else {
head = currNode->next;
delete currNode;
}
return currIndex;
}
return 0;
}
void List::DisplayList()
{
int num = 0;
Node* currNode = head;
while (currNode != NULL)
{
printf("\n%lf",currNode->data);
currNode = currNode->next;
num++;
}
printf("\nNumber of nodes in the list: %d",num);
}
List::~List(void) {
Node* currNode = head, *nextNode = NULL;
while (currNode != NULL)
{
nextNode = currNode->next;
// destroy the current node
delete currNode;
currNode = nextNode;
}
}
int main(int argc, char** argv) {
List list;
list.InsertNode(0,5.4); //başarılı
list.InsertNode(1,6.5); //başarılı
list.InsertNode(-2,5.5);//başarsız
list.InsertNode(2,10.0);//başarılı
list.DisplayList();
list.DeleteNode(5.4);
list.DisplayList();
return 0;
}
Now edit node part
class Node {
public:
int no;
char name[15];
char surname[15];
int age;
Node* next;
};
and insert function. Flow chart is here.
Node* List::InsertNode(int index, int no,char name[15],char surname[15],int age){
if (index < 0) return NULL;
int currIndex = 1;
Node* currNode = head;
while (currNode && index > currIndex) {
currNode = currNode->next;
currIndex++;
}
if (index > 0 && currNode == NULL) return NULL;
Node* newNode = new Node;
newNode->no = no;
strcpy_s(newNode->name, name);
strcpy_s(newNode->surname, surname);
strcpy_s(newNode->age, age);
if (index == 0) {
newNode->next = head;
head = newNode;
}
else {
newNode->next = currNode->next;
currNode->next = newNode;
}
return newNode;
}
Please point out the error in the code.
The function insertatend() inserts for the first time but not again.
I'm trying to insert a node at the end of a circular linked list, but after inserting an element for the first time, it gets stuck in the while loop if we try to enter data again.
struct node {
int data;
struct node *next;
};
typedef struct node node;
node *head = NULL;
node *insertatend(node *head, int value)
{
node *temp, *p;
p = head;
temp = (node *)malloc(sizeof(node));
temp->data = value;
temp->next = head;
if (head == NULL)
{
head = temp;
}
else
{
while (p->next != head)
p = p->next;
p->next = temp;
}
return head;
}
void display(node *head)
{
node *p = head;
if (head == NULL)
{
printf("\nlinked list is empty\n");
return;
}
while (p->next != head)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
int ch = 1, value;
while (ch)
{
printf("1.Insert 2.Display");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("enter an element:");
scanf("%d", &value);
head = insertatend(head, value);
break;
case 2:
display(head);
break;
}
}
return 0;
}
I think the mistake is here:
temp->next=head;
if(head==NULL){
head=temp;
}
When you enter your first element, head is null. So temp->next is set to NULL and head is set to temp.
When you enter your second element, it does this:
else{
while(p->next!=head)
p=p->next;
p->next=temp;}
Where p->next is null, so you will never have the situation that p->next == head and you will always be in the loop!
Edit:
So the solution aproach would be to change it to:
if(head==NULL){
head=temp;
}
temp->next=head;
Edit: second mistake in the display function: the loop doesn't print the last element. I just tested it and it is working fine.
So the complete code woud look like:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
typedef struct node node;
node *head = NULL;
node *insertatend(node *head, int value)
{
node *temp, *p;
p = head;
temp = (node *)malloc(sizeof(node));
temp->data = value;
if (head == NULL)
{
head = temp;
}
else
{
while (p->next != head)
p = p->next;
p->next = temp;
}
temp->next = head;
return head;
}
void display(node *head)
{
node *p = head;
if (head == NULL)
{
printf("\nlinked list is empty\n");
return;
}
do
{
printf("%d ", p->data);
p = p->next;
} while (p != head);
printf("\n");
}
int main()
{
int ch = 1, value;
while (ch)
{
printf("1.Insert 2.Display");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("enter an element:");
scanf("%d", &value);
head = insertatend(head, value);
break;
case 2:
display(head);
break;
}
}
return 0;
}
Alternate version, using tail pointer instead of head pointer, for faster appends.
#include <stdlib.h>
#include <stdio.h>
struct node {
struct node *next;
int data;
};
typedef struct node node;
node *insertatend(node *tail, int value)
{
node *p;
p = malloc(sizeof(node));
p->data = value;
if(tail == NULL){
p->next = p;
} else {
p->next = tail->next;
tail->next = p;
}
return p;
}
void display(node *tail)
{
node *p = tail;
if (p == NULL)
{
printf("\nlinked list is empty\n");
return;
}
do{
p = p->next;
printf("%d ", p->data);
}while(p != tail);
printf("\n");
}
int main()
{
node *tail = NULL;
int i;
for(i = 0; i < 8; i++)
tail = insertatend(tail, i);
display(tail);
return 0;
}
I put together a few pieces of code to make a linked list that adds to head(Has a special function) and in the middle(also special function).
my problem is, i need to provide the program with numbers and insert them as nodes in my LINKEDLIST. However, my display function(to display the tree of nodes) gives back segmentation fault and so does just taking values in without any display function.
I'm fairly new to malloc so i suspect the problem is there?
Thanks
#include<stdio.h>
#include<stdlib.h>
/*LINKEDLIST STRUCT*/
struct node {
int data;
struct node *next;
};
/*Inserting head-Node*/
struct node *insert_head(struct node *head, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = head;
head = temp;
return head;
}
/*Inserting inside a list*/
void after_me(struct node *me, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = me->next;
me->next = temp;
}
/*PRINTING LIST*/
void display(struct node *head)
{
struct node *moving_ptr = head;
while(moving_ptr != NULL)
{
printf("%d-->",moving_ptr->data);
moving_ptr = moving_ptr->next;
}
}
int main()
{
int index;
struct node *head;
struct node *previous_node;
scanf("%d", &index);
while(index > 0)
{
/*allocating in List */
if(head == NULL)
head = insert_head(head,index);
else
if((head != NULL) && (index <= (head->data)))
{
struct node *temp;
head->next = temp;
temp->next = head;/*TRY INSERT HEAD FUNC.*/
}
else
if((head != NULL) && (index > (head->data)))
{
previous_node->data = index-1;
after_me(previous_node,index);
}
scanf("%d", &index);
}
display(head);
}
I suggest as follows.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
//aggregated into one place
struct node *new_node(int number){
struct node *temp;
if(NULL == (temp = malloc(sizeof(*temp)))){
printf("\nNot enough memory\n");
exit(1);
}
temp->data = number;
temp->next = NULL;
return temp;
}
struct node *insert_head(struct node *head, int number) {
struct node *temp = new_node(number);
temp->next = head;
return temp;
}
void after_me(struct node *me, int number){
struct node *temp = new_node(number);
temp->next = me->next;
me->next = temp;
}
void display(struct node *head){
struct node *moving_ptr = head;
while(moving_ptr != NULL){
printf("%d", moving_ptr->data);
if(moving_ptr = moving_ptr->next)
printf("-->");
}
putchar('\n');
}
struct node *insert(struct node *me, int number){
if(me){
if(number <= me->data){
me = insert_head(me, number);
} else {
me->next = insert(me->next, number);
}
} else {
me = new_node(number);
}
return me;
}
void release(struct node *list){//Of course, you will be able to replace a simple loop(e.g while-loop).
if(list){
release(list->next);
free(list);
}
}
int main(void){
struct node *head = NULL;
int index;
while(1==scanf("%d", &index) && index > 0){
head = insert(head, index);
}
display(head);
release(head);
return 0;
}