linked list using double pointers - c

Using double pointers first time to create and display linked list
#include "stdio.h"
#include "stdlib.h"
struct node
{
int data;
struct node * next;
};
void Insert(struct node **, int , int );
void display(struct node *);
int main()
{
int c, data, position;
struct node* head;
do{
printf("Enter a choice :\n");
printf("1. Add an element.\n");
printf("2. Del an element.\n3.Display List.\n");
printf("4.Delete linked list.\n5.Exit.\n");
printf("Your Choice :");
scanf("%d",&c);
switch(c){
case 1 :
printf("\nEnter data and position :\n");
scanf("%d %d",&data,&position);
Insert(&head,data,position);
break;
case 2 :
break;
case 3 :
printf("Linked List : \n");
display(head);
break;
case 4 :
break;
case 5 :
exit(0);
default :
printf("Invalid Choice.\n");
break;
}
}while(1);
return 0;
}
void Insert(struct node **ptrhead, int item, int position){
struct node *p,*newnode;
//node creation.
newnode = (struct node *)malloc(sizeof(struct node));
if (!newnode)
{
printf("Memory Error.\n");
return;
}
newnode->next = NULL;
newnode->data = item;
p = *ptrhead;
// Creates initial node
if (!(p->data))
{
p = newnode;
}
// insertion at beginning
if (position==1)
{
newnode->next = p;
p = newnode;
free(newnode);
}
// insertionn at middle or end.
else
{
int i=1;
while(p->next!=NULL && i<position-1){
p=p->next;
i++;
}
newnode->next = p->next;
p->next = newnode;
}
*ptrhead = p;
};
// Display Linked list
void display(struct node *head){
if (head)
{
do{
printf("%d\n", head->data);
head = head->next;
}while(head->next);
}
};
I will add functions for deletion and other operations later. Right now , I just want to insert and display fns to work . But output comes as infinitely running loop with wrong values. I cannot figure out what's wrong in my code , please help ?
Thanks in advance.

Not sure why somebody would be writing this type of C today, looks like maybe I'm doing your homework for you... In any case, you asked to fix your code, not rewrite it, so here's the minimum set of changes.
head should be initialized to NULL.
if (!(p->data)) is not right. That if statement should just be:
// Creates initial node
if (!p)
{
*ptrhead = newnode;
return;
}
Remove free(newnode);.
The insert at middle/end code could be
int i = 1;
struct node *n = p;
while (n->next != NULL && i<position - 1){
n = n->next;
i++;
}
newnode->next = n->next;
n->next = newnode;
The final insert function:
void Insert(struct node **ptrhead, int item, int position)
{
struct node *p, *newnode;
//node creation.
newnode = (struct node *)malloc(sizeof(struct node));
if (!newnode)
{
printf("Memory Error.\n");
return;
}
newnode->next = NULL;
newnode->data = item;
p = *ptrhead;
// Creates initial node
if (!p)
{
*ptrhead = newnode;
return;
}
// insertion at beginning
if (position == 1)
{
newnode->next = p;
p = newnode;
}
// insertionn at middle or end.
else
{
int i = 1;
struct node *n = p;
while (n->next != NULL && i<position - 1){
n = n->next;
i++;
}
newnode->next = n->next;
n->next = newnode;
}
*ptrhead = p;
}
Your print function isn't quite right, just make it:
// Display Linked list
void display(struct node *head)
{
while (head)
{
printf("%d\n", head->data);
head = head->next;
}
}

Related

Polynominal with doubly linked list - pointer problem

I made some polynomial code with a doubly-linked list. for example, if
you write 1 and 2 then 1 is a degree and 2 is coefficient. 1x^2 insert
to doubly linked list. the problem is that when I check my code, the Node
head->degree is changing. if I write 1x^2 then head->degree is 1 next,
I write 2x^1 then head-> degree should maintain 1 but head-> degree
change to 2 I think there is some problem in the head pointer.
#include <stdio.h>
#include <stdlib.h>
// struct
struct Node {
int degree;
int coefficient;
struct Node* next;
struct Node* prev;
};
// global variables
int de; // degree
int co; // coefficient
int flag;
Node** head = (Node**)malloc(sizeof(Node)); //
Node** head1 = (Node**)malloc(sizeof(Node)); //
Node** head2 = (Node**)malloc(sizeof(Node)); //
Node** head3 = (Node**)malloc(sizeof(Node)); //
Node* newNode = (Node*)malloc(sizeof(Node)); //
// function
Node* inputpoly(void);
void printNode(Node* inp);
Node* multiply(Node* a, Node* b);
// main
int main() {
// head null
(*head1) = NULL;
(*head2) = NULL;
(*head3) = NULL;
while (1) {
printf("Input (degree) (coefficient) : ");
scanf_s("%d %d", &de, &co);
if (de * co < 0) { continue; }
if (de < 0 && co < 0) {
printf("Done!\n");
break;
}
*head = inputpoly();
}
printNode(*head);
//multiply(*head1, *head2);
free(head1);
free(head2);
free(head3);
free(newNode);
free(head);
}
Node* inputpoly(void) {
// create Node
newNode->degree = de;
newNode->coefficient = co;
newNode->next = NULL;
newNode->prev = NULL;
// case1
if (flag == 0) {
// list
if ((*head1) == NULL) {
*head1 = newNode;
}
// list x
else {
Node* horse = (*head1);
// front of head
// ------------------There is some problem
printf("%d\n", 1);
printf("--%d\n", newNode->degree);
printf("--%d\n", horse->degree);
if (horse->degree > newNode->degree) {
newNode->next = horse;
horse->prev = newNode;
*head1 = newNode;
}
// barward of head
else {
int num = 0;
while (horse->next != NULL) {
horse = horse->next;
if (horse->degree > newNode->degree) {
horse->prev->next = newNode;
newNode->next = horse;
newNode->prev = horse->prev;
horse->prev = newNode;
num = 1;
break;
}
}
// behind tail
if (num == 0) {
horse->next = newNode;
newNode->prev = horse;
}
}
}
return *head1;
}
}
void printNode(Node* inp) {
Node* horse = inp;
if (horse == NULL)
{
return;
}
while (horse != NULL) {
if (horse->prev == NULL) {
if (horse->degree == 1) {
printf("%d", horse->coefficient);
}
else {
printf("%d x^%d", horse->coefficient, horse->degree);
}
}
else {
if (horse->degree == 1) {
printf(" + %d", horse->coefficient);
}
else {
printf(" + %d x^%d", horse->coefficient, horse->degree);
}
}
}
printf("\n");
}
"i think there is some head pointer problem, and if I fixed it I can this problem. so I want to maintain this code as possible. I want some
advice or solution to my head pointer"
The code posted in your example does not compile:
Before you can fix a head pointer problem the code must compile. This list of errors is detailing 2 things:
first, functions cannot be called outside of a function, eg:
Node** head = (Node**)malloc(sizeof(Node)); //
Node** head1 = (Node**)malloc(sizeof(Node)); //
Node** head2 = (Node**)malloc(sizeof(Node)); //
Node** head3 = (Node**)malloc(sizeof(Node)); //
Node* newNode = (Node*)malloc(sizeof(Node)); //
should be called from within main(void){...} or some other function.
second, every occurrence of Node should be prepended with struct. eg:
struct Node** head = malloc(sizeof(struct Node *));
(have also removed the cast, and modified the size of what you are creating memory for, i.e. a pointer)
Rather then fix these and other problems, here is an example of a doubly linked list that can demonstrate the structure of a simple working program. You can adapt the following to match your needs:
struct Node {
int deg;
int coef;
struct Node* next; // Pointer to next node in DLL
struct Node* prev; // Pointer to previous node in DLL
};
void inputpoly(struct Node** head_ref, int deg, int coef)
{
//allocate node
struct Node *new_node = malloc(sizeof(*new_node));
//assign data
new_node->deg = deg;
new_node->coef = coef;
//set next as new head and prev to null
new_node->next = (*head_ref);
new_node->prev = NULL;
//change prev of head to new */
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
//point head to the new node */
(*head_ref) = new_node;
}
void printList(struct Node* node)
{
struct Node* last;
printf("\nread forward\n");
while (node != NULL) {
printf(" %d,%d ", node->deg,node->coef);
last = node;
node = node->next;
}
printf("\nread reverse\n");
while (last != NULL) {
printf(" %d,%d ", last->deg,last->coef);
last = last->prev;
}
}
int main(void)
{
//start with empty list
struct Node* head = NULL;
//create and populate new nodes
inputpoly(&head, 7, 2);
inputpoly(&head, 1, 4);
inputpoly(&head, 4, 6);
//ouput list
printList(head);
getchar();
return 0;
}
Note that this code is offered as a basic demonstration of creating doubly linked list, and illustrate how to traverse both directions. Because it does not free allocated memory, it is not recommended that it be used for any production purpose without addressing that omission.

In linked list ,when i write (temp->next=newnode) then when i apply temp=temp->next does not work but temp=newnode works?

Below is my code:
#include <stdio.h>
#include <stdlib.h>
int main() {
struct node {
int data;
struct node *next;
};
int choice;
struct node *head, *newnode, *temp;
head = 0;
while (choice) {
newnode = (struct node *)malloc(sizeof(struct node));
printf("enter items ");
scanf("%d", &newnode->data);
newnode->next = 0;
if (head == 0) {
head = temp = newnode;
} else
temp->next = newnode; /** **this is the problem** **/
temp = newnode; /** temp=newnode works but temp=temp->next doesn't**/
printf("do you want to continue");
scanf("%d", &choice);
}
temp = head;
while (temp != 0) {
printf("list is %d \n", temp->data);
temp = temp->next;
}
}
The problem is here:
if(head==0)
{
head=temp=newnode;
}
else
temp->next=newnode; /** **this is the problem** **/
temp=newnode; /** temp=newnode works but temp=temp->next doesn't**/
Indentation does not determine structure. You must enclose multiple instructions in a block to group them in the else clause. As coded, temp=newnode; is executed unconditionally after the test, which is not a problem, but redundant with head=temp=newnode.
Note also that choice is uninitialized when tested the first time.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
int main() {
struct node {
int data;
struct node *next;
};
int choice;
struct node *head, *tail, *newnode, *temp;
head = tail = NULL;
for (;;) {
newnode = (struct node *)malloc(sizeof(struct node));
if (newnode == NULL)
break;
printf("enter item: ");
if (scanf("%d", &newnode->data) != 1) {
free(nownode);
break;
}
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
tail->next = newnode;
}
tail = newnode;
printf("do you want to continue? [0/1] ");
if (scanf("%d", &choice) != 1 || choice == 0)
break;
}
for (temp = head; temp != NULL; temp = temp->next) {
printf("list is %d \n", temp->data);
}
return NULL;
}

Segfault while printing linked list after stack clear

To be more specific, this code is supposed to be a lesser clone of the Unix function dc. The linked list seems to be working fine. If I attempt to use c to clear the memory, add more numbers, then print again with f I get a segfault. It seems to be printing what should be the Null Node in the linked list.
Interaction:
$ ./test
1 2 3
f
3
2
1
c
4 5
f
5
4
0
Segmentation Fault
Here's the code itself:
#include <stdio.h>
#include <stdlib.h>
struct Node{
int val;
struct Node *next;
};
void cons_node(struct Node **head, int num)
{
struct Node *newNode = malloc(sizeof(struct Node));
newNode->val = num;
newNode->next = NULL;
if (*head == NULL){
*head = newNode;
}
else {
newNode->next = *head;
*head = newNode;
}
}
I'm assuming the problem lies here in the display func:
void display_list(struct Node *head)
{
struct Node *current = head;
while(current != NULL)
{
printf("%d\n", current->val);
current = current->next;}
}
void print_top(struct Node *head)
{
printf("%d\n", head->val);
}
or here in the clear func:
void clear_stack(struct Node *head)
{
struct Node *current;
while ((current = head)!= NULL) {
head = head->next;
free(current);
}
}
void vorpal_func(struct Node *head)
{
struct Node *current;
current = head;
free(current);
}
int main(){
int input;
int first = 1;
char quit = 'n';
char inputchar = ' ';
struct Node *head = NULL;
while (quit == 'n'){
if (scanf("%d", &input) == 1){
cons_node(&head, input);
first = 0;
}
else{
inputchar = getchar();
if(first == 1)
printf("List is empty\n");
else{
switch (inputchar){
case 'q':
quit = 'y';
break;
case 'E':
quit = 'y';
break;
case 'f':
display_list(head);
break;
case 'p':
print_top(head);
break;
case 'c':
clear_stack(head);
first = 1;
break;
case 't':
vorpal_func(head);
break;
}
}
}
}
return 0;
}
I've been attempting to figure out the problem for a few hours now. Any tips?
You don't clear your head after calling clear_stack, so when you add your next node, the next pointer is set to something that points into memory that has been freed. Or you could pass a pointer to head to clear_stack if you preferred.
void clear_stack(struct Node **head)
{
while (*head != NULL)
{
Node *current = *head;
*head = current->next;
free(current);
}
}
In passing, cons_node could be written like this
void cons_node(struct Node **head, int num)
{
struct Node *newNode = malloc(sizeof(struct Node));
newNode->val = num;
newNode->next = *head;
*head = newNode;
}

Doubly Linked List - Segmentation Faults - C

I am trying to implement a doubly linked list that acts like a queue (I want it to act like queue).
[EDIT]
When I add nodes to the list (e.g 5 nodes) and empty the list (delete all elements) and try to add another node to the list again, it gives me a segmentation fault (core dumped) error.
linkedlist.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node{
int d;
struct node *prev;
struct node *next;
}node;
typedef struct linkedlist{
int size;
struct node *first;
struct node *last;
}linkedlist;
linkedlist.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linkedlist.h"
linkedlist* createList(){
linkedlist* myList = (linkedlist*)calloc(1,sizeof(linkedlist));
myList->first = NULL;
myList->last = NULL;
myList->size =0;
return myList;
}
static node* createNode(int n){
node *myNode = (node*)calloc(1,sizeof(node));
myNode->d = n;
myNode->prev = NULL;
myNode->next = NULL;
return myNode;
}
void insertNode(linkedlist* l, int num){
node *temp, *newNode;
newNode = createNode(num);
if (l->size == 0){
newNode->next = NULL;
newNode->prev = NULL;
l->first = newNode;
l->last = newNode;
l->size++;
}
else{
temp = l->first;
while (temp->next != NULL){
temp = temp->next;
}
newNode->prev = temp;
temp->next = newNode;
newNode->next = NULL;
l->size++;
}
}
int deleteNode(linkedlist* l){
node *temp = calloc(1,sizeof(node));
if (l->first ==NULL){
return -1;
}
else if (l->size ==1){
free(l->first);
l->first= NULL;
l->last = NULL;
l->size--;
}
else if (l->size > 1){
temp = l->first;
l->first = temp->next;
free(temp);
}
}
void display(linkedlist *l){
node *temp = calloc(1,sizeof(node));
temp = l->first;
if (temp == NULL){
printf("The list is empty\n");
}
while (temp != NULL) {
printf("-> %d ", temp->d);
temp = temp->next;
}
}
int main(){
linkedlist *myList = createList();
int choice, temp=0, numb;
printf("(1) Insert \n (2) Delete \n");
for (temp; temp<10; temp++){
printf("Choice :");
scanf ("%d", &choice);
switch(choice) {
case 1: {
printf("Enter a Number: ");
scanf("%d", &numb);
insertNode(myList, numb);
display(myList);
break;
}
case 2:{
deleteNode(myList);
display(myList);
break;
}
}
}
}
In your delete node function:
else if (l->size > 1){
temp = l->first;
l->first = NULL; //this is problem
l->first->next = NULL;
temp->next = l->first;
l->first->prev = NULL;
You are assigning l->first = NULL and then accessing it in next statement l->first->next = NULL;, which will fail and give you segmentation fault.
Also, when l->size == 1 you should also set l->first = NULL after freeing it.
The problem appears when access to a "NULL" position. Let's revise the code:
temp = l->first;
l->first = NULL; // here, you set l->first = 0
l->first->next = NULL; // here, you access to 0->next: this is not correct.
temp->next = l->first;
Change it for:
temp = l->first;
l->first = temp->next;
delete temp;
int deleteNode(linkedlist* l){
node *temp= (node*)malloc(sizeof(node)) ;
if (l->first ==NULL){
return -1;
}
else
{
temp= l->first;
l->first= temp->next;
l->first->previous= temp;
l->size--;
free(l->first->previous);
}
}
In the deleteNode you leave first pointing to freed memory if the size is 1
It should be:
else if (l->size ==1){
free(l->first);
l->first = NULL;
l->last = NULL;
l->size--;
}
Also temp is a pointer you don't need to allocate memory for it with malloc

inserting an element in a linked list

Considering a linked list containing five elements.
1,2,3,4,5 a no '7' is to be inserted after two. we will have an head pointing to the first element of the linked list and ptr at the last. while inserting an element before 3 we will loop through the linked list starting from head to last and we will introduce another pointer(prev) to hold the previous pointers address.ptr will point to the current node and if a matching data is found(3) then we have to include the new node between 2 and 3.
We can do it as we have previous pointer.How to do it without using a previous pointer.
EDITED:
#include<stdio.h>
#include<stdlib.h>
struct list
{
int data;
struct list* link;
};
struct list *head=NULL;
struct list *tail=NULL;
void createList(int value);
void displayList(struct list* head_node);
void insertNewNode();
int value;
int main()
{
int i;
for(i=0;i<5;i++)
{
printf("\nEnter the data to be added into the list:\n");
scanf("%d",&value);
createList(value);
}
printf("\nCreated Linked list is\n");
//displayList(head);
printf("\nInsert a node\n");
insertNewNode();
displayList(head);
return 0;
}
void insertNewNode()
{
int val;
struct list* ptr=NULL,*new_node,*prev=NULL;
new_node = (struct list*)malloc(sizeof(struct list));
printf("Enter the data to be inserted!");
scanf("%d",&val);
for(ptr=head;ptr;ptr=ptr->link)
{
if(ptr->data == 3)
{
printf("Found");
new_node->data = val;
prev->link=new_node;
new_node->link = ptr;
}
prev = ptr;
}
}
void createList(int value)
{
struct list *newNode;
newNode = (struct list*)malloc(sizeof(struct list));
//tail = (struct list*)malloc(sizeof(struct list));
newNode->data = value;
if(head == NULL)
{
head = newNode;
}
else
{
tail->link = newNode;
}
tail = newNode;
tail->link = NULL;
}
void displayList(struct list *head_node)
{
struct list *i;
for(i=head;i;i=i->link)
{
printf("%d",i->data);
printf(" ");
}
printf("\n");
}
void insertNewNode()
{
int val;
struct list* ptr=NULL,*new_node;
new_node = (struct list*)malloc(sizeof(struct list));
printf("Enter the data to be inserted!");
scanf("%d",&val);
for(ptr=head;ptr;ptr=ptr->link)
{
if(ptr->data == 2)
{
printf("Found");
new_node->data = val;
new_node->link = ptr->link;
ptr->link = new_node;
}
}
}
Update:
This is probably what you want:
void insertNewNode()
{
int val;
struct list* ptr=NULL,*new_node;
new_node = (struct list*)malloc(sizeof(struct list));
printf("Enter the data to be inserted!");
scanf("%d",&val);
for(ptr=head;ptr->link;ptr=ptr->link)
{
if(ptr->link->data == 3)
{
printf("Found");
new_node->data = val;
new_node->link = ptr->link;
ptr->link = new_node;
}
}
}
Here:
if(ptr->link->data == 3)
you simply look ahead to check if next node has value that you need.
Let's call curr the pointer at the current element, next the pointer at the next element, and value the number stored.
Traverse the list until curr.value == 2, now just create a new_node with new_node.value = 7 and set new_node.next = curr.next and curr.next = new_node

Resources