insert linked list nodes in a loop - c

I'm using strtok() to parse an input, convert the string into an int and then insert this int value into a linked list all in a while loop.
This is what I'm trying to do (I haven't written the code explicitly but I'm planning to do do something as follows):
while(fgets(&string,LMAX,fp) != NULL){
//get first token using strtok
//convert to int
//insert into linked list
while (token != NULL){
//get next token in the line
//do the same as above
}
}
I already have written a function that is supposed to insert a node into the linked list and it is as follows:
void insert_node(struct Cons *head_pointer, int data){
struct Cons *new = (struct Cons*) malloc(sizeof(struct Cons));
struct Cons *current = head_pointer;
new->head = data;
new->tail = NULL;
if (head_pointer->tail == NULL){
head_pointer->tail = new;
}
else
{
while (current->tail != NULL){
current = current->tail;
}
current->tail = new;
}
free(current);
current = NULL;
}
The struct definition is also as follows:
typedef int element_t;
typedef
struct Cons {
element_t head;
struct Cons* tail;
} Cons;
Can anyone suggest how I can go about doing this?

Change the code like this
Cons *insert_node(Cons *head_pointer, int data){
Cons *new = (struct Cons*) malloc(sizeof(struct Cons));
Cons *current = head_pointer;
new->head = data;
new->tail = NULL;
if (head_pointer== NULL){
head_pointer->tail = new;
}
else
{
while (current->tail != NULL){
current = current->tail;
}
current->tail = new;
}
//free(current);
//current = NULL;
return head_poiner;
}
in a main() function call like;
main()
{
..........
..........
while(fgets()!=NULL){
head_pointer=insert_node(head_pointer,data);
.........
.........
}

This is my code I have experimented.
# include <stdio.h>
# include <stdlib.h>
struct node
{
int data;
struct node *link;
};
struct node *insert(struct node *p, int n)
{
struct node *temp;
/* if the existing list is empty then insert a new node as the
* starting node */
if(p==NULL)
{
if((p=(struct node *)malloc(sizeof(struct node)))==NULL)
{
perror("Error");
exit(0);
}
p-> data = n;
p-> link = p; /* makes the pointer pointing to itself because it
is a circular list*/
}
else
{
temp = p;
/* traverses the existing list to get the pointer to the last node of
* it */
while (temp-> link != p)
temp = temp-> link;
if((temp-> link = (struct node *)malloc(sizeof(struct node)))==NULL)
{
perror("Error\n");
exit(0);
}
temp = temp-> link;
temp-> data = n;
temp-> link = p;
}
return p;
}
void printlist ( struct node *p )
{
struct node *temp;
temp = p;
printf("The data values in the list are\n");
if(p!= NULL)
{
do
{
printf("%d\t",temp->data);
temp=temp->link;
} while (temp!= p);
printf("\n");
}
else
printf("The list is empty\n");
}
void main()
{
int n;
int x;
struct node *start = NULL ;
char buf[BUFSIZ];
while(fgets(buf,BUFSIZ,stdin)!=NULL){
x=atoi(buf);
start = insert ( start, x );
}
printlist ( start );
}

Related

How can I delete the front node of my doubly linked list?

I want to delete the front node in delete_first.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
typedef int element;
typedef struct DListNode {
element data;
struct DListNode *llink;
struct DListNode *rlink;
} DlistNode;
void init(DListNode *phead) {
phead->llink = phead;
phead->rlink = phead;
}
An error occurs in the part below when I debug.
void print_dlist(DListNode *phead) {
DListNode *p;
for (p = phead->rlink; p != phead; p = p->rlink) {
printf("<-| |%d| |->", p->data);
}
printf("\n");
}
This is my insert code and I think it is not problem
void dinsert(DListNode *before, element data) {
DListNode *newnode = (DListNode *)malloc(sizeof(DListNode));
newnode->data = data;
newnode->llink = before;
newnode->rlink = before->rlink;
before->rlink->llink = newnode;
before->rlink = newnode;
}
I want to fix some error in that delete_first code but I don't know what is the problem and how to fix it.
void delete_first(DListNode *head) {
head = head->rlink;
if (head != NULL) {
head->llink = NULL;
}
free(head);
}
int main() {
DListNode *head = (DListNode *)malloc(sizeof(DListNode));
init(head);
printf("insert\n");
for (int i = 0; i < 5; i++) {
dinsert(head, i);
print_dlist(head);
}
printf("\n delete \n");
delete_first(head);
print_dlist(head);
free(head);
return 0;
}
How can I delete my front node using the head node?
To delete the first node of the doubly linked list, you must free the node pointed to by head->rlink unless head->rlink points to head itself, which is the case if the list is empty:
void delete_first(DListNode *head) {
DListNode *p = head->rlink;
if (p != head) {
p->llink->rlink = p->rlink;
p->rlink->llink = p->llink;
free(head);
}
}

Not able to add to the head of a Linked List

I've created a program that would insert a node into a linked list based on alphabetical order (A-Z). I'm able to do it, however, I'm not able to insert at the front of the linked list. We can assume that the list is never initially empty. Any help? Here is my code with the relevant structs. The problem is where // Inserting at the front of the list
typedef struct fileNode {
char *tokenName; // hi
double token; // 0.5
struct fileNode *next;
} fileNode;
typedef struct fileStruct {
char *name; // a.txt
int numberOfTokens; // 4
fileNode *tokenLL;
struct fileStruct *next;
} fileStruct;
void insertLL(struct fileNode *list, char *token){
struct fileNode *ptr = list;
struct fileNode *prev = NULL;
struct fileNode *newNode = malloc(sizeof(struct fileNode));
newNode->tokenName = token;
newNode->token = 1;
bool inserted = false;
while (ptr != NULL && inserted == false) {
if (strcmp(ptr->tokenName, token) > 0){
count++;
if (prev == NULL){ // Inserting at the front of the list
newNode->next = ptr;
ptr = newNode;
list = newNode;
inserted = true;
return;
}
else {
prev->next = newNode;
newNode->next = ptr;
inserted = true;
}
} // end of if
prev = ptr;
ptr = ptr->next;
} // end of while
if (!inserted){
prev->next = newNode;
} // adding to the end of the list
}
To modify the direct object pointed by *list , you need to declare it as a **list in your function arguments.
if you declare it as a *list you're going to modify the object *list only inside the function. It's because when you call a function the arguments used inside the called function are a copy of the variables used to call the function in the calling function.
#include <stdio.h>
void add(int x,int y){
x=y;
}
void add_ptr(int *x,int y){
*x=y;
}
int main(int argc, char *argv[]) {
int x=1;
int y=2;
add(x,y);
printf("add\t x:%d\n",x);
add_ptr(&x,y);
printf("add_ptr\tx:%d\n",x);
return 0;
}
if you declare it as a **list you're going to modify the object pointed at the adress pointed by **list when you set: *(list)=Newnode; (the change is going to be permanent )
void insertLL(struct fileNode **list, char *token){
struct fileNode *ptr = *list;
struct fileNode *prev = NULL;
struct fileNode *newNode = malloc(sizeof(struct fileNode));
newNode->tokenName = token;
newNode->token = 1;
bool inserted = false;
while (ptr != NULL && inserted == false) {
if (strcmp(ptr->tokenName, token) > 0){
count++;
if (prev == NULL){ // Inserting at the front of the list
newNode->next = *list; /*it's easier to understand with only *list*/
*list = newNode;
inserted = true;
return;
}
else {
prev->next = newNode;
newNode->next = ptr;
inserted = true;
}
} // end of if
prev = ptr;
ptr = ptr->next;
} // end of while
if (!inserted){
prev->next = newNode;
} // adding to the end of the list
}

Removing element from linked list (if found) without deleting it from memory

I have understood how deletion works in linked list, however the implementation is harder than I thought.
I have written this below but it is not working sadly
My node:
struct DLinkedList
{
double sensorData;
struct DLinkedList *prev;
struct DLinkedList *next;
};
And this is my delete function:
void delete(struct DLinkedList **first, struct DLinkedList *el)
{
struct DLinkedList* temp = *first;
if (temp != NULL && temp->sensorData == el->sensorData)
{
(*first) = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->sensorData == el->sensorData)
{
temp->prev = temp;
temp = temp->next;
}
if (temp == NULL)
{
return;
}
free(temp);
}
Is there something wrong with the code itself? The compiler is not giving me any errors but the function doesn't seem to work properly, the way I call it in main() is delete(&first, el);
Here is my main, I have added 3 elements excluding el so that I can see the list more clearly:
int main()
{
//Adding 3 nodes
struct DLinkedList* first = NULL;
struct DLinkedList* second = NULL;
struct DLinkedList* last = NULL;
struct DLinkedList* el = NULL;
//Allocating 3 nodes
first = malloc(sizeof(struct DLinkedList));
second = malloc(sizeof(struct DLinkedList));
last = malloc(sizeof(struct DLinkedList));
el = malloc(sizeof(struct DLinkedList));
first->sensorData = 1; //Assigning data for 'first' node
first->next = second; //Link first node with second node
first->prev = NULL;
second->sensorData = 2;
second->next = last;
second->prev = first;
last->sensorData = 3;
last->next = NULL;
last->prev = second;
el->sensorData = 10;
el->next = first;
el->prev = NULL;
insertFirst(&first, el);
printList(first);
isMember(&first, el);
delete(&first, el);
return 0;
}
//Printing contents of the linked list starting from the 'first' node
void printList(struct Node* first)
{
while (first != NULL)
{
printf(" %f ", first->data);
first = first->next;
}
}
Here below is my minimal example, I have made some changes in the names and main in order to be more readable
#include <stdio.h>
#include <stdlib.h>
//A linked list node
struct Node
{
double data;
struct Node* prev;
struct Node* next;
};
void delete(struct Node** first, struct Node* el)
{
if (*first == el)
{
*first = el->next;
}
if (el->prev)
{
el->prev->next = el->next;
}
if (el->next)
{
el->next->prev = el->prev;
}
free(el);
}
int main()
{
struct Node* first = NULL;
struct Node* el = NULL;
el = malloc(sizeof(struct Node));
el->data = 10;
el->next = NULL;
el->prev = NULL;
delete(&first, el);
print(first);
return 0;
}
You're complicating it much more than necessary. If you have a doubly linked list, use it's abilities.
void delete(struct DLinkedList **first, struct DLinkedList *el) {
// We only need to change the pointer to the first element
// if that's the element we're deleting
if(*first == el)
*first = el->next;
// The old switcheroo
if(el->prev)
el->prev->next = el->next;
if(el->next)
el->next->prev = el->prev;
// Free and we're done. Skip this line if you want to keep the node
// and only remove it from the list.
free(el);
}
This could be combined with a convenient find function:
struct DLinkedList *find(struct DLinkedList **first, double val) {
struct DLinkedList ret = *first;
while(ret && ret->sensorData != val)
ret = ret->next;
return ret;
}
However, you should be careful comparing float numbers. Read more here: What is the most effective way for float and double comparison?
It seems you're trying to reuse an "element" struct as the "list" struct for a doubly linked list.
Although you can reuse next/prev as head/tail, I recommend a separate header struct:
Here's what I mean. Note that I renamed the struct slightly to be more descriptive of purpose:
// element of list
typedef struct element Element;
struct element {
double sensorData;
Element *next;
Element *prev;
};
// list header
typedef struct list List;
struct list {
Element *head;
Element *tail;
};
void
delete(List *list,Element *el)
{
Element *next;
Element *prev;
next = el->next;
prev = el->prev;
if (next != NULL)
next->prev = prev;
if (prev != NULL)
prev->next = next;
if (list->head == el)
list->head = next;
if (list->tail == el)
list->tail = prev;
}

How to delete nodes of a linked list between two indices?

I have the following linked list implementation:
struct _node {
char *string;
struct _node *next;
}
struct _list {
struct _node *head;
struct _node *tail;
}
I want to make the following function:
void deleteList(struct _list *list, int from, int to) {
int i;
assert(list != NULL);
// I skipped error checking for out of range parameters for brevity of code
for (i = from; i <= to; i++) {
deleteNode(list->head, i);
}
}
// I ran this function with this linked list: [First]->[Second]->NULL
like this deleteNodes(list, 1, 1) to delete the second line and got
[First]->[Second]->NULL but when I run it like this deleteList(list, 0, 1) with this input [First]->[Second]->[Third]->NULL I get a seg fault.
Here is my deleteNode function
void deleteNode(struct _node *head, int index) {
if (head == NULL) {
return;
}
int i;
struct _node *temp = head;
if (index == 0) {
if (head->next == NULL) {
return;
}
else {
head = head->next;
free(head);
return;
}
}
for (i = 0; temp!=NULL && i<index-1; i++) {
temp = temp->next;
}
if (temp == NULL || temp->next == NULL) {
return;
}
Link next = temp->next->next;
free(temp->next);
temp->next = next;
}
I wrote a separate function to delete the head of the linked list if from or to = 0:
void pop(struct _node *head) {
if (head == NULL) {
return;
}
struct _node *temp = head;
head = head->next;
free(temp);
}
but it gives me seg fault or memory error Abort trapL 6.
It's all good to use just one struct, a node for your purpose.
struct node {
char *string;
struct node *next;
};
Then your loop for removing elements between two indices will not delete the right elements if you don't adjust the index according to the changing length of the list. And you must also return the new head of the list.
struct node *deleteList(struct node *head, unsigned from, unsigned to) {
unsigned i;
unsigned count = 0;
for (i = from; i <= to; i++) {
head = delete_at_index(head, i - count);
count++;
}
return head;
}
The help function delete_at_index looks as follows.
struct node *delete_at_index(struct node *head, unsigned i) {
struct node *next;
if (head == NULL)
return head;
next = head->next;
return i == 0
? (free(head), next) /* If i == 0, the first element needs to die. Do it. */
: (head->next = delete_at_index(next, i -
1), head); /* If it isn't the first element, we recursively check the rest. */
}
Complete program below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char *string;
struct node *next;
};
void freeList(struct node *head) {
struct node *tmp;
while (head != NULL) {
tmp = head;
head = head->next;
free(tmp->string);
free(tmp);
}
}
struct node *delete_at_index(struct node *head, unsigned i) {
struct node *next;
if (head == NULL)
return head;
next = head->next;
return i == 0
? (free(head), next) /* If i == 0, the first element needs to die. Do it. */
: (head->next = delete_at_index(next, i -
1), head); /* If it isn't the first element, we recursively check the rest. */
}
struct node *deleteList(struct node *head, unsigned from, unsigned to) {
unsigned i;
unsigned count = 0;
for (i = from; i <= to; i++) {
head = delete_at_index(head, i - count);
count++;
}
return head;
}
void pushvar1(struct node **head_ref, char *new_data) {
struct node *new_node = malloc(sizeof(struct node));
new_node->string = strdup(new_data);
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printListvar1(struct node *node) {
while (node != NULL) {
printf(" %s ", node->string);
node = node->next;
}
printf("\n");
}
int main(int argc, char **argv) {
struct node *head = NULL;
for (int i = 0; i < 5; i++) {
char str[2];
sprintf(str, "node%d", i);
pushvar1(&head, str);
}
puts("Created Linked List: ");
printListvar1(head);
head = deleteList(head, 0, 2);
puts("Linked list after deleted nodes from index 0 to index 2: ");
printListvar1(head);
freeList(head);
return 0;
}
Test
Created Linked List:
node4 node3 node2 node1 node0
Linked list after deleted nodes from index 0 to index 2:
node1 node0
every programming problem can be solved by adding an extra level of indirection: use a pointer to pointer ...
unsigned deletefromto(struct node **head, unsigned from, unsigned to)
{
unsigned pos,ret;
struct node *this;
for (pos=ret=0; this = *head;pos++) {
if (pos < from) { head = &(*head)->next; continue; }
if (pos > to) break;
*head = this->next;
free(this);
ret++;
}
return ret; /* nuber of deleted nodes */
}

sorting a singly linked list with quicksort after user input and then inserting a new node and resorting list

I have my code for the most part but having a rough go of it trying to get my quick sort function to work and sort through the actual link list created. Don't know if I am calling the function improperly or if I have the struct correct.
The program will compile and run up until it gets to the calling function for the quicksort. Then it just freezes and does nothing. Any help would be great. Thank you a head of time.
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *link_list;
};
struct node *insertion(struct node *pointer, int i){
struct node *temp_val;
if(pointer == NULL){
pointer = (struct node *)malloc(sizeof(struct node));
if(pointer == NULL){
printf("Error Exiting\n");
exit(0);
}
pointer->data = i;
pointer->link_list = pointer;
}else{
temp_val = pointer;
while(temp_val->link_list != pointer){
temp_val = temp_val->link_list;
}
temp_val->link_list = (struct node *)malloc(sizeof(struct node));
if(temp_val->link_list == NULL){
printf("Error Exiting\n");
exit(0);
}
temp_val = temp_val->link_list;
temp_val->data = i;
temp_val->link_list = pointer;
}
return(pointer);
};
struct node *findPivot(struct node *head, struct node *term, struct node **newHead, struct node **newTerm){
struct node *pivot = term;
struct node *previous = NULL, *current = head, *tail = pivot;
//finding the pivot and dividing the list while also updating the head and term
// with newHead and newTerm
while(current != pivot){
if(current->data < pivot->data){
//assigning the newHead to the first value less then the pivot
if((*newHead) == NULL){
(*newHead) = current;
}
previous = current;
current = current->link_list;
}else{
// if the current node has a higher value then the pivot
// assinging it to newTerm
if(previous){
previous->link_list = current->link_list;
}
struct node *temp = current->link_list;
current->link_list = NULL;
tail->link_list = current;
tail = current;
current = temp;
}
}
//Checks the case if the pivot is the smallest value and moves to head
if((*newHead)== NULL){
(*newHead) = pivot;
}
(*newTerm) = tail; // makes sure the last element is newEnd
return pivot;
}
//finds the last node in the list and returns it
struct node *getTail(struct node *current){
while(current != NULL && current->link_list != NULL){
current = current->link_list;
}
return current;
}
// the actual recursive quicksort algorithm
struct node *quickSort(struct node *head, struct node *term){
if(!head || head == term) //base case for the recursion
return head;
struct node *newHead = NULL, *newTerm = NULL;
// the recursive case
struct node *pivot = findPivot(head, term, &newHead, &newTerm);
//no need for recursion if pivot is smallest value
if(newHead != pivot){
struct node *temp = newHead;
while(temp->link_list != pivot){
temp = temp->link_list;
}
temp->link_list = NULL;
newHead = quickSort(newHead, temp);
temp = getTail(newHead);
temp->link_list = pivot;
}
pivot->link_list = quickSort(pivot->link_list, newTerm);
return newHead;
}
void quickSortFunction(struct node **pointer){
*pointer = quickSort(*pointer, getTail(*pointer));
return;
}
void printList_Unsorted(struct node *pointer){
struct node *temp;
temp = pointer;
printf("\nThe Data values in the list are:\n");
if(pointer != NULL){
do{
printf("%d\t", temp->data);
temp = temp->link_list;
}while(temp != pointer);
}else{
printf("the list is empty\n");
}
}
void printList_Sorted(struct node *node){
while(node!= NULL){
printf("%d ", node->data);
node = node->link_list;
}
printf("\n");
}
int main(int argc, char *argv[]) {
int num_nodes, node_val;
struct node *list = NULL;
printf("Enter the number of nodes to be created: ");
scanf("%d", &num_nodes);
while(num_nodes --> 0){
printf("\n\nEnter the data values to be placed in a node: ");
scanf("%d", &node_val);
list = insertion(list, node_val);
}
printf("\n\nThe Created list is as follow:\n");
printList_Unsorted(list);
printf("\n");
quickSortFunction(&list);
printList_Sorted(list);
//getchar();
//getchar();
return 0;
}
Please look at this working example.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *link_list;
};
void insertion(struct node **pointer, int i) {
struct node *temp_val = malloc(sizeof *temp_val);
temp_val->data = i;
temp_val->link_list = (*pointer);
(*pointer) = temp_val;
}
/* A utility function to print linked list */
void printList(struct node *node) {
while (node != NULL) {
printf("%d ", node->data);
node = node->link_list;
}
printf("\n");
}
// Returns the last node of the list
struct node *getTail(struct node *current) {
while (current != NULL && current->link_list != NULL)
current = current->link_list;
return current;
}
struct node *findPivot(struct node *head, struct node *term,
struct node **newHead, struct node **newTerm) {
struct node *pivot = term;
struct node *previous = NULL, *current = head, *tail = pivot;
while (current != pivot) {
if (current->data < pivot->data) {
if ((*newHead) == NULL)
(*newHead) = current;
previous = current;
current = current->link_list;
}
else
{
if (previous)
previous->link_list = current->link_list;
struct node *tmp = current->link_list;
current->link_list = NULL;
tail->link_list = current;
tail = current;
current = tmp;
}
}
// If the pivot data is the smallest element in the current list,
// pivot becomes the head
if ((*newHead) == NULL)
(*newHead) = pivot;
// Update newTerm to the current last node
(*newTerm) = tail;
// Return the pivot node
return pivot;
}
// the actual recursive quicksort algorithe
struct node *quickSort(struct node *head, struct node *end) {
// base case
if (!head || head == end)
return head;
struct node *newHead = NULL, *newEnd = NULL;
struct node *pivot = findPivot(head, end, &newHead, &newEnd);
if (newHead != pivot) {
struct node *tmp = newHead;
while (tmp->link_list != pivot)
tmp = tmp->link_list;
tmp->link_list = NULL;
newHead = quickSort(newHead, tmp);
tmp = getTail(newHead);
tmp->link_list = pivot;
}
pivot->link_list = quickSort(pivot->link_list, newEnd);
return newHead;
}
void quickSortFunction(struct node **headRef) {
(*headRef) = quickSort(*headRef, getTail(*headRef));
return;
}
int main() {
struct node *list = NULL;
int num_nodes, node_val;
printf("Enter the number of nodes to be created: ");
scanf("%d", &num_nodes);
while(num_nodes --> 0){
printf("\n\nEnter the data values to be placed in a node: ");
scanf("%d", &node_val);
insertion(&list, node_val);
}
printf("\n\nThe Created list is as follows:\n");
printList(list);
printf("\n");
quickSortFunction(&list);
printList(list);
return 0;
}
Test
/home/dac/.CLion2016.2/system/cmake/generated/gnu-fadf49ce/fadf49ce/Debug/gnu
Enter the number of nodes to be created: 3
Enter the data values to be placed in a node: 2
Enter the data values to be placed in a node: 4
Enter the data values to be placed in a node: 3
The Created list is as follows:
3 4 2
2 3 4
Process finished with exit code 0
The problem with your code was that it entered an infinite loop because the parameter was not a pointer to the node, but a pointer to the struct. You also don't need to return the list because you are passing it by reference.

Resources