Binary Search Tree - Level order traversal in C - c

I was trying out the code for level order traversal in a binary search tree using a queue and I don't know why I'm getting no output when I try to print the level order. Someone please help!
Link to my code.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int data;
struct Node *right, *left;
}Node;
typedef struct
{
int front, rear, size;
unsigned capacity;
Node* arr[100];
}Queue;
Queue* createQ()
{
Queue* q = (Queue*) malloc(sizeof(Queue));
q->capacity = 100;
q->front = q->size = 0;
q->rear = q->capacity - 1;
return q;
}
int isEmpty(Queue* q)
{
return (q->size == 0);
}
int isFull(Queue* q)
{
return (q->size == q->capacity);
}
void enqueue(Queue* q, Node* item)
{
if (isFull(q))
return;
q->rear = (q->rear + 1)%q->capacity;
q->arr[q->rear] = item;
q->size = q->size + 1;
}
Node* dequeue(Queue* q)
{
if (isEmpty(q))
return NULL;
Node* item = q->arr[q->front];
q->front = (q->front + 1)%q->capacity;
q->size = q->size - 1;
return item;
}
Node* create(Node* root, int data)
{
if(root==NULL)
{
root = (Node*)malloc(sizeof(Node));
root->data = data;
root->left = root->right = NULL;
return root;
}
else
{
if(data>root->data)
{
root->right = create(root->right,data);
}
else
{
root->left = create(root->left,data);
}
return root;
}
}
void levelorder(Node* root)
{
if(root==NULL) return;
else
{
Queue* q = createQ();
enqueue(q,root);
while(isEmpty(q))
{
Node* temp = dequeue(q);
printf("%d ",temp->data);
if(temp->right)
enqueue(q,temp->right);
else if(temp->left);
enqueue(q,temp->left);
}
}
}
void main()
{
int data;
Node *root = NULL;
for(;;)
{
printf("\nEnter the elements (-1 to stop) : ");
scanf("%d",&data);
if(data==-1) break;
root = create(root,data);
}
printf("\nPrinting the elemtents in level order : ");
levelorder(root);
}

You have several bugs in your levelorder function. Please check the corrections below. I've kept your buggy line in side comment.
void levelorder(Node* root)
{
if(root==NULL) return;
else
{
Queue* q = createQ();
enqueue(q,root);
while(!isEmpty(q)) // not while(isEmpty(q)) you have to check untill Queue is non-empty
{
Node* temp = dequeue(q);
printf("%d ",temp->data);
if(temp->right)
enqueue(q,temp->right);
if(temp->left) // not else if(temp->left); there can be right node and left node as well.. no semicolon
enqueue(q,temp->left);
}
}
}
Rest of the code is okay. You should practice debugging yourself using some well-known IDE.

In line 83, while(isEmpty(q)) should be while(!isEmpty(q)) because we would want to run the loop while the Queue is non-empty.
I hope I got the bug right.

Related

Unable to understand why my C code runs correctly on Linux and WSL2 but not on pure windows [duplicate]

This question already has answers here:
What exactly is the value contained in an uninitialized local variable in C?
(2 answers)
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 3 months ago.
I have written a code which performs some basic operations on binary search tree. My code runs perfectly on linux ecosystems like Ubuntu or WSL2 but gives incorrect output in windows ecosystem more specifically Windows 10. Here's my code
#include <stdio.h>
#include <malloc.h>
typedef struct TreeNode
{
int data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
typedef struct node
{
TreeNode *data;
struct node *next;
} node;
typedef struct queue
{
node *head;
node *tail;
int size;
} queue;
TreeNode *insert_in_bst(int element, TreeNode *root);
TreeNode *delete_in_bst(int element, TreeNode *root);
void inorder(TreeNode *root);
void levelwise(TreeNode *root);
void enqueue(queue *q, TreeNode *root);
node *dequeue(queue *q);
void mirror_image(TreeNode *root);
int height(TreeNode *root);
int main(int argc, char *argv[])
{
int n = 0;
printf("Enter elements to be added to bst - ");
scanf("%d", &n);
TreeNode *root;
while (n != -1)
{
root = insert_in_bst(n, root);
scanf("%d", &n);
}
levelwise(root);
printf("\nCurrent inorder - ");
inorder(root);
int del;
printf("\nEnter element to delete - ");
scanf("%d", &del);
delete_in_bst(del, root);
levelwise(root);
printf("\nNew inorder - ");
inorder(root);
printf("\nMirror image\n");
mirror_image(root);
levelwise(root);
int h = height(root);
printf("\nHeight = %d", h);
return 0;
}
TreeNode *insert_in_bst(int element, TreeNode *root)
{
if (!root)
{
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
newNode->data = element;
return newNode;
}
if (element < root->data)
{
root->left = insert_in_bst(element, root->left);
}
else
{
root->right = insert_in_bst(element, root->right);
}
return root;
}
TreeNode *delete_in_bst(int element, TreeNode *root)
{
if (!root)
return NULL;
if (element < root->data)
{
root->left = delete_in_bst(element, root->left);
}
else if (element > root->data)
{
root->right = delete_in_bst(element, root->right);
}
else
{
if (!root->left)
return root->right;
else if (!root->right)
return root->left;
else
{
TreeNode *curr = root->right;
while (!curr->left)
curr = curr->left;
root->data = curr->data;
root->right = delete_in_bst(curr->data, root->right);
}
}
return root;
}
void inorder(TreeNode *root)
{
if (!root)
return;
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
void levelwise(TreeNode *root)
{
node *currNode = (node *)malloc(sizeof(node));
currNode->data = root;
queue *q = (queue *)malloc(sizeof(queue));
enqueue(q, root);
while (q->size != 0)
{
int l = q->size;
for (int i = 0; i < l; i++)
{
node *temp = dequeue(q);
TreeNode *t = temp->data;
printf("%d ", t->data);
if (t->left)
{
enqueue(q, t->left);
}
if (t->right)
{
enqueue(q, t->right);
}
}
printf("\n");
}
}
void enqueue(queue *q, TreeNode *root)
{
node *temp = (node *)malloc(sizeof(node));
temp->data = root;
if (!q || !q->head)
{
q->head = temp;
q->tail = temp;
q->size = 1;
}
else
{
q->tail->next = temp;
q->tail = q->tail->next;
q->size++;
}
}
node *dequeue(queue *q)
{
node *top = q->head;
q->head = q->head->next;
q->size--;
return top;
}
void mirror_image(TreeNode *root)
{
if (!root)
return;
TreeNode *temp = root->left;
root->left = root->right;
root->right = temp;
mirror_image(root->left);
mirror_image(root->right);
}
int height(TreeNode *root)
{
if (!root)
return 0;
int lh = height(root->left);
int rh = height(root->right);
return 1 + (lh > rh ? lh : rh);
}
Heres the output on Windows ecosystems
Here's the output on linux/wsl2
On further debugging on Windows systems, i found out that by default; value to root is assigned as 1. On linux systems this thing doesnt happen. Can someoe help me find out the reason?
Thank you!

How to declare and access a pointer to a member of a member struct in C?

So, I am relatively new to C and trying to implement a Queue using Linked Lists. Here is some code I wrote with help from the internet.
#include <stdio.h>
#include <stdlib.h>
#define pscan(prompt, x) printf(prompt); scanf("%d", &x)
#define nl() printf("\n");
typedef struct Node {
int data;
struct Node* next;
} Node;
typedef struct LinkedList {
Node* head;
Node* tail;
int size;
int (*add) (struct LinkedList*, int, int);
int (*append) (struct LinkedList*, int);
int (*get) (struct LinkedList*, int);
int (*remove) (struct LinkedList*, int);
void (*display_list) (struct LinkedList*);
Node* (*createNode) (int);
} LinkedList;
int add (LinkedList* self, int data, int position);
int append (LinkedList* self, int data);
int get (LinkedList* self, int position);
int rmv (LinkedList* self, int position);
void display_list (LinkedList* self);
LinkedList createLinkedList ();
Node* createNode (int data);
int add(LinkedList* self, int data, int position)
{
if (position > self->size || position < 0)
{
printf("Index out of bounds\n");
return 0;
}
Node* newNode = self->createNode(data);
Node* head = self->head;
Node* tail = self->tail;
if (position == 0)
{
if (head == NULL) self->head = newNode;
else
{
if (tail == NULL) tail = head;
newNode->next = head;
self->head = newNode;
}
self->size++;
}
else if (position == self->size)
{
if (head == NULL) self->head = newNode;
else
{
if (tail == NULL) tail = head;
tail->next = newNode;
self->tail = newNode;
}
self->size++;
}
else
{
Node* prev = head;
for(int i = 0; i < position-1; i++)
{
prev = prev->next;
}
Node* node = prev->next;
prev->next = newNode;
newNode->next = node;
self->size++;
}
return 0;
}
int append(LinkedList* self, int data)
{
return self->add(self, data, self->size);
}
int get(LinkedList* self, int position)
{
if (self->size == 0)
{
printf("The list is empty.");
return 0;
}
else if (position >= self->size || position < 0)
{
printf("Index out of bound.");
return 0;
}
if (position == 0) return self->head->data;
else if (position+1 == self->size) return self->tail->data;
else
{
Node* node = self->head;
for(int i = 0; i < position; i++) node = node->next;
return node->data;
}
}
int rmv (LinkedList* self, int position)
{
int dt;
if (self->size == 0)
{
printf("The list is empty.");
return 0;
}
else if (position >= self->size || position < 0)
{
printf("Index out of bound");
return 0;
}
if (position == 0)
{
Node* head = self->head;
Node* next = head->next;
self->head = next;
dt = head->data;
free(head);
self->size--;
}
else if (position+1 == self->size)
{
Node* node = self->head;
Node* tail = self->tail;
for(int i = 0; i < self->size-2; i++) node = node->next;
node->next = NULL;
self->tail = node;
dt = tail->data;
free(tail);
self->size--;
}
else
{
Node* prev = self->head;
Node* next;
Node* node;
for(int i = 0; i < position-1; i++) prev = prev->next;
node = prev->next;
next = node->next;
prev->next = next;
dt = node->data;
free(node);
self->size--;
}
return dt;
}
void display_list(LinkedList* self)
{
if (self->size == 0) printf("This list is empty.\n\n");
else
{
Node* node = self->head;
printf("[");
for (int i = 0; i < self->size; i++)
{
if (i > 0) printf(", ");
printf("%d", node->data);
node = node->next;
}
printf("]\n\n");
}
}
Node* createNode (int data)
{
Node* node = (Node*) malloc(sizeof(Node));
node->data = data;
node->next = NULL;
return node;
}
LinkedList createLinkedList ()
{
LinkedList l;
l.head = NULL;
l.tail = NULL;
l.add = &add;
l.append = &append;
l.get = &get;
l.remove = &rmv;
l.display_list = &display_list;
l.createNode = &createNode;
l.size = 0;
return l;
}
typedef struct queue
{
LinkedList items;
int *size;
int (*enqueue) (struct queue*, int);
int (*dequeue) (struct queue*);
int (*peek) (struct queue*, int);
void (*display) (struct queue*);
} Queue;
Queue CreateQueue();
int enqueue(Queue* self, int item);
int dequeue(Queue* self);
int peek(Queue* self, int pos);
void display(Queue* self);
Queue CreateQueue()
{
Queue q;
q.items = createLinkedList();
q.size = &(q.items.size);
q.enqueue = &enqueue;
q.dequeue = &dequeue;
q.peek = &peek;
q.display = &display;
return q;
}
int enqueue(Queue* self, int item)
{
self->items.append(&(self->items), item);
return 1;
}
int dequeue(Queue* self)
{
return self->items.remove(&(self->items), 0);
}
int peek(Queue* self, int pos)
{
return self->items.get(&(self->items), pos);
}
void display(Queue* self)
{
printf("%d items in queue.\n", *(self->size));
self->items.display_list(&(self->items));
}
void main()
{
Queue q = CreateQueue();
q.enqueue(&q, 3);
q.enqueue(&q, 7);
q.enqueue(&q, 4);
q.display(&q);
int item = q.dequeue(&q);
printf("Dequeued: %d\n", item);
q.display(&q);
q.enqueue(&q, 14);
q.display(&q);
}
The part I'm having an issue with is making the Queue's size pointer point to the LinkedList's size integer and then accessing that value.
On compiling and running, I get this:
Output from the above code
Thanks in advance.
The problem is in createQueue:
Queue CreateQueue()
{
Queue q;
q.items = createLinkedList();
q.size = &(q.items.size);
q.enqueue = &enqueue;
q.dequeue = &dequeue;
q.peek = &peek;
q.display = &display;
return q;
}
You set q.size to point to q.items.size. This is a pointer to a local variable. You then return a copy of q, but the size member now points to a local that doesn't exist. Dereferencing a pointer to a variable whose lifetime has ended triggers undefined behavior.
There's no need for the size element in Queue. Just access the size element of the items member directly.

Circular doubly linked list in C delete function

I have a circular doubly linked list.
The deletefront() function is not working: the output is wrong. What is the mistake?
The other functions are working. But I get a wrong output after displaying after calling deletefront function. The 100 value which should be deleted is still appearing. Please correct it.
I have included the C source code:
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *rlink;
struct node *llink;
} node;
node *head = NULL;
node *getnode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
void insertfront(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
head->llink = newnode;
newnode->rlink = head;
head = newnode;
}
}
void insertend(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
node *temp = head;
do {
temp = temp->rlink;
} while (temp != head->llink);
newnode->rlink = temp->rlink;
temp->rlink = newnode;
newnode->llink = temp;
}
}
int lenlist() {
node *temp;
int count = 0;
temp = head;
do {
temp = temp->rlink;
count++;
} while (temp != head);
return count;
}
void insertatpos(int ele,int pos) {
if (pos == 1) {
insertfront(ele);
} else
if (pos == (lenlist() + 1)) {
insertend(ele);
} else
if (pos > 1 && pos <= (lenlist() + 1)) {
node *prev, *curr;
node *newnode = getnode(ele);
int count = 1;
curr = head;//curr points to 1st node
do {
prev = curr;
count++;
curr = curr->rlink;
if (count == pos) {
prev->rlink = newnode;
newnode->llink = prev;
newnode->rlink = curr;
curr->llink = newnode;
}
} while (curr != head);
} else {
printf("invalid position");
}
}
void delfront() {
if (head == NULL)
printf("empty list");
node *aux;
node *lastnode, *secondnode;
aux = head;
lastnode = head->llink;
secondnode = head->rlink;
secondnode->llink = lastnode;
lastnode->rlink = secondnode;
free(aux);
head = secondnode;
}
void display() {
node *aux = head;
do {
printf("%d->", aux->data);
aux = aux->rlink;
} while (aux != head);
printf("\n");
}
int main() {
insertfront(100);
insertend(20);
printf("\n%d\n", lenlist());
insertatpos(45, 2);
display();
delfront();
display();
}
The problem is not in the deletefront() function, instead, you have missed updating a few links in the insertfront() and insertend() functions.
I have updated the code here and also added the comment where I made the changes. Try to visualise it using an example.
However, I suggest that you solve such issues using a debugger or go through the code with a sample test case. It will improve you debugging as well as coding skills!
Your code have a lot of mistakes.
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
/*i changed the names of your pointers here*/
typedef struct node {
int data;
struct node *prev, *next;
} node;
/*
node *head = NULL;
This will be removed.
Avoid using globals as much as you can.
*/
/*
This function is unecessary.
node *createNode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
*/
char insertFront(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
}
*head=newNode;
return 1;
}
char insertEnd(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
*head=newNode;
}
return 1;
}
/*You could simple create a struct list that would have as members
the head of your list and its height to avoid calculating it each time
you want it but anyway. I will fix that.
int lenList(node *head) {
if (*head==NULL) return 0;
node *temp=head;
int count = 0;
do {
temp = temp->next;
count++;
} while (temp != head);
return count;
}
*/
char insertNatP(node **head, int ele, int pos) {
If (pos<1 || pos>lenList(head)){
printf("Invalid Position\n");
return 0;
}
int i;
for(i=0; i<pos-1; head=&head->next, i++);
node *newNode=malloc(sizeof(node));
If (newNode==NULL){
printf("Memory could not be allocated\n");
return 0;
}
newNode->data=ele;
If (*head!=NULL){
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode
newNode->next=*head;
} else {
newNode->prev=newNode;
newNode->next=newNode;
}
*head=newNode;
return 1;
}
char delFront(node **head) {
if (*head == NULL) return 0;
node garbage=*head;
*head=(*head)->next;
if (*head==garbage) *head=NULL; else{
(*head)->prev=garbage->prev;
garbage->prev->next=*head;
}
free(garbage);
return 1;
}
void printList(node *list) {
if (list==NULL) return;
node *sentinel=list->prev;
while (list!=sentinel) {
printf("%d->", list->data);
list=list->next;
}
printf("%d\n", list->data);
}
int main() {
node *l1=NULL;
insertFront(&l1, 100);
insertEnd(&l1, 20);
printf("\n%d\n", lenList(l1));
insertNatP(&l1, 45, 2);
printList(l1);
delFront(&l1);
printList(l1);
}
Try this

Saving pointer to last node in doubly linked list when performing insertion sort

Here I have a header file to include functions:
#ifndef driver_h
#define driver_h
#include <stdio.h>
#include <stdlib.h>
typedef struct node node;
typedef struct nodePtrs nodePtrs;
struct node {
node* next;
node* prev;
int data;
};
void sortedInsert(node** top, node* newNode, node** last) {
node* current;
if (*top == NULL) {
*top = newNode;
} else if ((*top)->data >= newNode->data) {
newNode->next = *top;
newNode->next->prev = newNode;
*top = newNode;
if ((*top)->next == NULL) {
*last = *top;
}
} else {
current = *top;
while (current->next != NULL &&
current->next->data < newNode->data) {
current = current->next;
}
newNode->next = current->next;
if (current->next != NULL) {
newNode->next->prev = newNode;
}
current->next = newNode;
newNode->prev = current;
}
if ((*top)->next == NULL) {
*last = *top;
}
}
void insertionSort(node** top, node** last) {
node* sorted = NULL;
node* current = *top;
while (current != NULL) {
node* next = current->next;
current->prev = current->next = NULL;
sortedInsert(&sorted, current, last);
current = next;
}
*top = sorted;
}
node* deleteByPos(node* list, node** last, int position) {
int c = 0;
node* temp;
node* prev;
temp=list;
if (temp==NULL) {
printf("No nodes available to delete\n\n");
return list;
} else {
while(temp!=NULL && c != position) {
prev=temp;
temp=temp->next;
c++;
}
if (temp==NULL) {
printf("Reached end of list, position not available\n\n");
return list;
} else if (temp->next == NULL) {
prev->next=temp->next;
*last = prev;
free(temp);
return list;
} else {
prev->next=temp->next;
temp->next->prev = prev;
free(temp);
return list;
}
}
}
node* makeNode(int n) {
node* np = malloc(sizeof (node));
np->data = n;
np->prev = NULL;
np->next = NULL;
return np;
}
void printList(node* np) {
while (np != NULL) {
printf("%d\n", np->data);
np = np->next;
}
}
void printListReverse(node* np) {
while (np != NULL) {
printf("%d\n", np->data);
np = np->prev;
}
}
#endif /* driver_h */
and a main file:
#include "driver.h"
int main() {
int n;
node* np;
node* top;
node* last;
printf("Enter integers to add to list\n");
do {
if (scanf("%d", &n) != 1) {
n = 0;
}
if (n != 0) {
np = makeNode(n);
if (top == NULL) {
top = np;
} else {
last->next = np;
np->prev = last;
}
last = np;
}
} while (n != 0);
printf("\n\n");
printf("You entered:\n");
printList(top);
printf("\n\n");
printf("In reverse:\n");
printListReverse(last);
printf("\n\n");
printf("Enter a position to delete:");
scanf("%d", &n);
top = deleteByPos(top, &last, n);
printf("\n\n");
printf("In reverse after delete:\n");
printListReverse(last);
insertionSort(&top, &last);
printf("From top after sort:\n");
printList(top);
printf("In reverse after Sort:\n");
printListReverse(last);
}
What this program does is take user input of integers, stores them in a doubly linked list, deletes a node at a user defined point and then performs an insertion sort. What I am trying to do is save a pointer to the last node in the sortedInsert function with the following code:
if ((*top)->next == NULL) {
*last = *top;
}
However, if you enter 6 5 3 1 9 8 4 2 7 4 2, then delete at position 2, when printing in reverse it prints out 6 5 4 4 2 2 1. For some reason it skips over 9 7 8. I cannot figure out why or how to fix this. How can I do this properly?
With lists, it helps to draw a diagram for all the cases. It's natural to use induction on lists to prove your code is correct.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h> /* Asserting is useful when it come to lists especially. */
struct node {
struct node* next;
struct node* prev;
int data;
};
/* Saves you from dealing with 'top' and 'tail' every time. */
struct list {
struct node *head, *tail;
};
/* https://en.wikipedia.org/wiki/Insertion_sort */
void insertionSort(struct list* list) {
struct node* i = list->head, *j0, *j1;
while(i) {
j1 = i, j0 = j1->prev;
while(j0 && j0->data > j1->data) {
/* Swap. */
int temp = j0->data;
j0->data = j1->data;
j1->data = temp;
/* Decrement. */
j1 = j0;
j0 = j0->prev;
}
i = i->next;
}
}
/* Returns whether the position was deleted. */
int deleteByPos(struct list* list, int position) {
struct node* n;
assert(list);
/* Node n is the position's in the list. */
for(n = list->head; n && position; n = n->next, position--);
if (n==NULL) {
printf("No nodes available to delete\n\n");
return 0;
}
/* Fixme: If I'm not mistaken, there are 9 cases for you to be
mathematically certain this works, and I haven't tried them all.
Eg, 1 node, 2 nodes x2, 3 nodes x3, where the internal node is the 2nd of
the 3 nodes. */
if(n->prev == NULL) {
/* The first one. */
assert(list->head == n);
list->head = n->next;
if(n->next) n->next->prev = NULL;
} else {
/* Skip over. */
n->prev->next = n->next;
}
if(n->next == NULL) {
/* The last one. */
assert(list->tail == n);
list->tail = n->prev;
if(n->prev) n->prev->next = NULL;
} else {
/* Skip over. */
n->next->prev = n->prev;
}
n->prev = n->next = NULL; /* Helps in debugging. */
free(n);
return 1;
}
struct node* makeNode(struct list *list, int n) {
struct node* np = malloc(sizeof *np);
if(!np) return 0;
np->data = n;
np->prev = list->tail;
np->next = NULL;
/* Push it in the list. */
if(list->tail) {
assert(list->head != NULL && list->tail->next == NULL);
list->tail->next = np;
} else {
/* The first one. */
assert(list->head == NULL && list->tail == NULL);
list->head = np;
}
list->tail = np;
return np;
}
void printList(const struct list*const list) {
const struct node *n = list->head;
while (n) {
printf("%d\n", n->data);
n = n->next;
}
}
void printListReverse(const struct list*const list) {
const struct node *n = list->tail;
while (n) {
printf("%d\n", n->data);
n = n->prev;
}
}
int main(void) {
int n;
struct list list = { 0, 0 };
printf("Enter integers to add to list\n");
while(scanf("%d", &n) == 1 && n)
if(!makeNode(&list, n)) return perror("node"), EXIT_FAILURE;
printf("\n\n");
printf("You entered:\n");
printList(&list);
printf("\n\n");
printf("In reverse:\n");
printListReverse(&list);
printf("\n\n");
printf("Enter a position to delete:");
scanf("%d", &n);
printf("You entered %d.\n", n);
deleteByPos(&list, n);
printf("\n\n");
printf("In reverse after delete:\n");
printListReverse(&list);
insertionSort(&list);
printf("From top after sort:\n");
printList(&list);
printf("In reverse after Sort:\n");
printListReverse(&list);
return EXIT_SUCCESS;
}
*One would ideally free memory on exit.
It is usually much simpler to use a sentinel node rather than NULL to indicate the end of a list. So an empty list consists of a node whose head and tail point to itself. Once you add elements, sentinel->next is the first in the list and sentinel->prev is the last in the list. This removes many of the cases you have to test for NULL in your code:
#ifndef driver_h
#define driver_h
#include <stdio.h>
#include <stdlib.h>
typedef struct node node;
typedef struct nodePtrs nodePtrs;
struct node {
node* next;
node* prev;
int data;
};
void sortedInsert(node* top, node* newNode) {
node* current = top;
while (current->next != top &&
current->next->data < newNode->data) {
current = current->next;
}
newNode->next = current->next;
newNode->next->prev = newNode;
current->next = newNode;
current->next->prev = current;
}
void insertionSort(node* top) {
node* current = top->next;
// make top an empty ring so can append to it
top->next = top->prev = top;
while (current != top) {
node* next = current->next;
sortedInsert(top, current);
current = next;
}
}
node* deleteByPos(node* top,int position) {
int c = 0;
node* temp = top->next;
while (true) {
if (temp == top) {
printf("Reached end of list, position not available\n\n");
return top;
}
if (c == position) {
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
free(temp);
return top;
}
temp = temp->next;
c++;
}
}
node* makeNode(int n) {
node* np = malloc(sizeof(node));
np->data = n;
np->prev = np;
np->next = np;
return np;
}
void printList(node* top) {
for (node* np = top->next; np != top; np = np->next) {
printf("%d\n", np->data);
}
}
void printListReverse(node* top) {
for (node* np = top->prev; np != top; np = np->prev) {
printf("%d\n", np->data);
}
}
#endif /* driver_h */
main file :
#include "driver.h"
int main() {
int n;
node* np;
node* top;
top= makeNode(0);
printf("Enter integers to add to list\n");
do {
if (scanf_s("%d", &n) != 1) {
n = 0;
}
if (n != 0) {
np = makeNode(n);
np->prev = top->prev;
top->prev = np;
top->prev->next = top;
np->prev->next = np;
}
} while (n != 0);

Implementation of Stacks using Linked List. Where am I going wrong?

This is the code I've written in C :
#include<stdio.h>
struct Node
{
int info;
struct Node *next;
};
void init_Node(struct Node *n)
{
n->next = NULL;
}
struct Node *front = NULL;
void display()
{
struct Node *rear = front;
if(rear == NULL)
printf("List is empty!\n");
else
{
printf("[%i]-->",rear->info);
rear = rear->next;
}
printf("NULL");
printf("\n");
}
void addEnd(int x)
{
struct Node *n = malloc(sizeof(struct Node));
struct Node *rear = front;
n->info = x;
if(front == NULL)
front = n;
else
{
while(rear->next != NULL)
rear = rear->next;
rear->next = n;
rear = n;
}
display();
}
void deleteEnd()
{
struct Node *rear = front;
if(front == NULL)
printf("Stack is Empty!");
else
{
while(rear->next->next != NULL)
{
rear = rear->next;
}
printf("Popped : %i\n", rear->next->info);
rear->next = NULL;
display();
}
}
int main()
{
struct Node *n = malloc(sizeof(struct Node));
init_Node(n);
clrscr();
addEnd(23);
addEnd(45);
addEnd(8);
addEnd(57);
deleteEnd();
addEnd(98);
deleteEnd();
getch();
return 0;
}
The below output is the output when the implementation was done in C++ using classes.
The output for the program was supposed to be this -
but the output of my code is this -
EDIT
After adding the while() loop and adding n->next = NULL; the output comes out to be :
Where am I going wrong?
You need two changes:
void display()
{
struct Node *rear = front;
if(rear == NULL)
printf("List is empty!\n");
else
{
// CHANGE 1: You need a while loop here
while(rear != NULL) {
printf("[%i]-->",rear->info);
rear = rear->next;
}
}
printf("NULL");
printf("\n");
}
void addEnd(int x)
{
struct Node *n = malloc(sizeof(struct Node));
struct Node *rear = front;
n->info = x;
// CHANGE 2: You need to clear n->next to NULL.
n->next = NULL;
if(front == NULL)
front = n;
else
{
while(rear->next != NULL)
rear = rear->next;
rear->next = n;
rear = n;
}
display();
}
in your function, addEnd() you need to initialize the next pointer to zero. So, right after the line n->info = x; add a line n->next = 0;

Resources