How pop is working in stack using linked list? - c++

Here in the pop function, after top is assigned to temp, its written top=top->link, but how is top=top->link making it point to its back node?
top=top->link is meant to move forward and point to the node to its front and here it should be NULL.
EDIT: cout added in pop. Now to make question more specific, how cout<<top->data will print 32 ? it should be pointing to NULL.
#include<iostream>
using namespace std;
class stack_ll{
private:
struct node{
int data;
node *link;
}*top;
public:
stack_ll()
{
top=NULL;
}
void push(int);
void pop();
void display();
~stack_ll()
{
if(top==NULL)
return;
node *temp;
while(top!=NULL)
{
temp=top;
top=top->link;
delete temp;
}
}
};
void stack_ll::push(int num)
{
node *temp;
temp=new node;
if(temp==NULL) {
cout<<"stack is full"<<endl;
return;
}
temp->data=num;
temp->link=top;
top=temp;
}
void stack_ll::pop(){
if(top==NULL)
{
cout<<"stack is empty"<<endl;
return;
}
node * temp;
int item;
temp=top;
item=temp->data;
top=top->link;
cout<<top->data<<endl;
delete temp;
}
int main()
{
stack_ll l1;
l1.push(5);
l1.push(56);
l1.push(32);
l1.push(34);
l1.pop();
l1.push(23);
l1.pop();
}

You are right. Pop here will remove the first object and will now have top as NULL even though there are some objects in the stack. What you should do to fix that, is change the link direction - meaning each object will point to the lower object. In that case, when removing the top, you will be able to retrieve the next object, that is lower in the stack
change:
temp->data=num;
temp->link=top;
top=temp;
to:
temp->data=num;
top->link=temp;
top=temp;
and add a special case for an empty stack where top->link=temp; will not be legal like:
if(top==NULL){
temp->data=num;
top=temp;
top->link=NULL;
}
EDIT:
your logic should be like this:
empty stack has only a null_ptr (top)
push: if stack is empty - top is now new element and it's link is null_ptr, else - top's link is now new element, top becomes new element and new element's link is null_ptr
pop: if stack is empty do nothing, else - print top's data, save top as temp, top becomes top's link (the lower element in stack), print temp's data and delete temp

This implementation is correct. You don't need to change anything.
Working of push
When we try to add an element is this stack, we create a new node and make it head of the link list. Hence the last element added will always be head of the link list.
Working of of Pop
When we try to pop an element we just do top- = top->link. This means we just changed the head node to the previous element which was added in the stack.

Related

Segmentation fault (core dumped) - Threaded Binary Search Tree

I keep getting the following error : Segmentation fault (core dumped) . I found out the line of code that is causing the problem ( marked with a comment inside of the program) . Please tell me why this error is happening and how to fix it.
I've tried to dry run my code (on paper ) and see no logical errors (from my understanding).
I have only recently got into coding and stackoverflow please guide me through how I can further improve my question , as well as my code . Thanks !
class tree
{
struct node // Creates a node for a tree
{
int data;
bool rbit,lbit; // rbit/lbit= defines if right/left child of root is present or not
node *left,*right;
};
public:
node *head,*root;
tree() // constructor initializes root and head
{
root=NULL;
head=createnode(10000);
}
node *createnode(int value)
{// Allocates memory for a node then initializes node with given value and returns that node
node *temp=new node ;
temp->data=value;
temp->lbit=0;
temp->rbit=0;
temp->left=NULL;
temp->right=NULL;
return temp;
}
void insert(node *temp,int value) // Creates binary search tree node by node
{
if(root==NULL) // Checking if tree is empty
{
root=createnode(value); //Root now points to new memory location
head->left=root;
head->lbit=1;
root->left=head;//this line gives the segmentation fault (what i thought before correction)
}
}
void inorder(node *root) // Inorder traversal of tree (this function is logically incorrect)
{
if(root==NULL)
return;
inorder(root->left);
cout<<root->data<<"\t";
inorder(root->right);
}
void getdata()//Accepts data , creates a node through insert() , displays result through inorder()
{
int data;
cout<<"Enter data"<<endl;
cin>>data;
insert(root,data);
inorder(root);
}
/*void inorder(node *root) // Working inorder code
{
if(root->lbit==1)
inorder(root->left);
cout<<root->data<<"\t";
if(root->rbit==1)
inorder(root->right);
}*/
};
int main()
{
tree t; // Tree Object
t.getdata(); // Calling getdata
return 0;
}
I think the comments section largely reflects a miscommunication. It's easy to believe that you are experiencing a crash ON that particular line.
This is not actually the case. Instead what you have done is created a loop in your tree which leads to infinite recursion by the inorder function. That causes a stack overflow which segfaults -- this would have been extremely easy to spot if you had just run your program with a debugger (such as gdb) attached.
temp = createnode(value);
if(root == NULL)
{
root = temp;
head->left = root;
head->lbit = 1;
temp->left = head;
}
Look at the loop you have just created:
head->left points to root
root->left == temp->left, which points to head
An inorder traversal will now visit:
root
head
root
head
root
head
...
Since it never gets to the end of the left-branch, the function never outputs anything before overflowing the stack and crashing.
So no, your code is not logically correct. There's a fundamental design flaw in it. You need to rethink what you are storing in your tree and why.
From the code,
root=temp; //Root now points to temp
head->left=root;
head->lbit=1;
temp->left=head;// this line gives the segmentation fault
root is not pointing to temp. temp(pointer) is assigned to root(pointer).
head's left pointer is root, and temp's left is head (which means root's left is head). so in the function "inorder",
void inorder(node *root) // Inorder traversal of tree
{
if(root==NULL) <<<<<<
return;
inorder(root->left);
cout<<root->data<<"\t";
inorder(root->right);
}
the argument node *root (left) is never NULL and the function never return.
There's not enough information on exactly how this should work (what is node.lbit for example).
The question's insert() function will not work. It's passing in a value which is immediately overwritten (among other issues). There's no explanation of what tree.head is for, so it's ignored. The fields node.lbit and node.rbit look to be superfluous flags of node.left != NULL (similarly for right). These are omitted too. The insert() is also not creating the tree properly.
void insert(int value) // Insert a value into the tree (at branch)
{
// Create a new node to insert
struct node *temp = createnode(value);
if (root == NULL) // Checking if tree is empty
{
root = temp; //Root now points to temp
}
else
{
insertAtBranch(root, temp);
}
}
// recursively find the leaf-node at which to insert the new node
void insertAtBranch(node *branch, node *new_node)
{
// to create a BST, less-than go left
if (new_node->value <= branch->value)
{
if (branch->left == NULL)
branch->left = new_node; // There's no left-branch, so it's the node
else
insertAtBranch(branch->left, new_node); // go deeper to find insertion point
}
else // greater-than go right
{
if (branch->right == NULL)
branch->right = new_node;
else
insertAtBranch(branch->right, new_node);
}
}
Imagine how a binary tree works. New nodes are only ever inserted at the edges. So you look at a given node, and decide if this new-node is less or grater than the one you're looking at (unless the tree is empty, of course).
Say the new-node.value is less than the branch-node.value, you want to branch left. Still with the same node, if it doesn't have a left-branch (node.left == NULL), the new node is the left branch. Otherwise you need to travel down the left-branch and check again.
I would have made node a class, and used a constructor to at least set the default properties and value. But that's not a big deal.

Insertion at end of linked list using recursion vs Iteration

The function to insert at end of linked list using recursion looks something like this
// Main..
for(int i=0;i<n;i++){
cin>>x;
insert(head,x);
}
void insert(struct node*&h,int x){
if(h==NULL){
h=new node(x);
return;
}
insert(h->next,x);
}
But if I am doing same with iteration it doesn't work the same way,Its making only one node.
void insert(struct node* &h,int x){
if(h==NULL){
h=new node(x);
return;
}
struct node* go=h;
while(go){ //At (go==NULL) it should point to next of last node
go=go->next; // I know it should be go->next!=NULL condition.
}
go=new node(x);//Assigning next of last to new node.
}
I am having serious mental blockage.Can anyone please help why it doesn't work ? What should I do to make it work ?
The problem here is that you loop until go is not null. Okay, once fixed, you loop until go is null,
Then you just overwrite a null pointer by a new. But that doesn't link it to your existing list.
Do that instead:
void insert(struct node* &h,int x)
{
if(h==NULL)
{
h=new node(x);
return;
}
struct node* go=h;
// move until last element
while(go->next)
{
go=go->next;
}
// create a node at the end
go->next=new node(x);//Assigning next of last to new node.
}
At first iteration, go is guaranteed to be non-null (checked by first if condition).
Just check for the first next element to be null, and insert your new node here.

Segfault-Iterative insert in BST

I'm trying to write a code to insert a new element in the BST iteratively. When I try to execute the code, I get a segfault. Can someone look over the code and help me correct it?
bool insert2(int item)
{
BstNode *parent;
BstNode *root=new BstNode;
cout<<root->data;
cout<<"\n";
BstNode *ptr;
int ctr=0;
//cout<<root->data;
if (root==NULL)
{
BstNode *temp=new BstNode;
temp->data=item;
temp->left=NULL;
temp->right=NULL;
root=temp;
//cout<<root->data;
return true;
}
else
{
ptr=root;
while (ptr!=NULL)
{
ctr=ctr+1;
cout<<ctr;
if (ptr->data==item)
{
cout<<ptr->data;
return false;
}
if (item < ptr->data)
{
parent=ptr;
ptr=ptr->left;
}
else
{
parent=ptr;
ptr=ptr->right;
}
}
BstNode *add=new BstNode;
add->data = item;
add->left= NULL;
add->right= NULL;
return true;
}
}
on editing out the root-> data part, the code would go into the first if block and return true, which makes me guess that my problem lies somewhere in the deceleration.
There are a number of things that you are doing wrong. First of all, as PaulMcKenzie has pointed out, you should not be creating the root at the beginning of the function. If the BST does not start out empty, the root already exists and you do not want to create a new one. Instead, the root should be a public variable (which would only allow you to have one BST), or the function should take a pointer to the root as one of the parameters. It certainly does not make sense that you create the root and then test it to see if it is NULL. Unless you ran out of memory, it would not be NULL right after you created it.
Another problem with your code is that after you find the appropriate location in the BST, you create the new node, but do not attach it to the tree. Instead, you might want to insert the following lines after you initialize add:
if(item < parent->data)
parent->left = add;
else
parent->right = add;
As far as the fact that you get a seg-fault every time you call the function, it is probably because, when you declare root, you do not initialize its right and left pointers to NULL. Therefore, the while loop does not stop when it reaches root->left or root->right. When you try to deference ptr later in the loop, you are deferencing an uninitialized pointer, resulting in a seg-fault.

BST insertion with C++

I created a function to insert data to a BST and it works fine. I used "pass by reference" and the value of "head" is supposed to change after each insertion. However, I found that the "head" is always pointing to the first value that I inserted. Could anyone here explain what causes the "head" to point to the first data I inserted?
void insert(node *&head, int val){
if(head == NULL){
head = newNode(val);
}
else{
if(val <head->data)
insert(head->left,val);
else
insert(head->right,val);
}
}
that is how the function should work, head should never change or you will lose track of the tree root.
as long as you have the head pointing at the root, you have access to the whole tree.
the reason why the value is not changing is, when you are writing insert(head->left,val);
you are not assigning a new value to head, you are just passing the reference to the left child to the next function call.
void insert(node *&head, int val){
if(head == NULL){
head = newNode(val); // when you call insert() with pointer to root
// which is NULL this will create root node
}
then when you add data to the root node (whch is not NULL anymore)
else{ // this will be called and this doesn't create new root node
// but just create nodes at its left or right side
if(val <head->data)
insert(head->left,val);
else
insert(head->right,val);
}
}

C++ - Stack with Linked List - Bad Memory Error?

I am currently writing stack that is being implemented with a linked list. I am get this error:
Unhandled exception at 0x75249617 in STACK_LinkedList.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x002ee8f8.
I believe it is possibly coming from either my push() or pop() functions. I can't find my error. I am fairly new to linked lists, so I have a little bit of a tough time finding errors.
Here is my push() function:
// Adds an item to the top of the stack
template <class S>
void Stack<S>::push(const S & e)
{
NodePointer temp = new Node(e);
if ( isEmpty() )
{
theTop = theFront = temp;
}
else
{
// Whatever is after top is stored in temp to keep track of it
theTop->next = temp;
// TheTop is stored in temp
theTop = temp;
delete temp;
}
}
Here is my pop() function:
//Takes the item off the top of the stack
template <class S>
void Stack<S>::pop()
{
if ( !isEmpty() )
{
//temp node is set equal to the front
NodePointer temp = theFront;
//Holds the second to last node in the linked list
NodePointer pred;
//loops through until the node after temp is 0
while (temp->next != 0)
{
//sets the second to last as temp
pred = temp ;
//basically "increments" temp to the next node
temp = temp->next ;
}
//sets temp equal to the top
temp = theTop;
//the top is then set to its predecessor
theTop = pred;
//deletes what was known as the top
delete temp;
}
else
cout << "STACK IS EMPTY" << endl;
}
Thanks alot! I believe most of my logic is correct. I just am missing something small. If it's something else please tell me and i'll post that code.
You should not delete your temp in push! It's a part of the list. So when you access this data later, you get surely an exception.
Second, you have to initialize your pred with NULL in pop(), otherwise you'll get an undefined value assigned to theTop if the stack contains only 1 item.
Third, you should delete in pop() the Node which you allocated in push().
In general, your approach seems to be not very efficient. You should better store the pointers other way round: from stack top to the bottom items. That way you won't need to traverse the whole stack on each pop(). Your code will be something like that:
void push(data)
{
allocate new top
new top's next is the old top
store new top in the class
}
void pop()
{
if empty, ERROR;
new top = old top's next
deallocate old top
}
Note that you don't need theFront at all.
Your push function is deleting "temp". However, temp points to the data you just added to your list. If call delete on a pointer, you are not throwing away the pointer, but rather deleting the memory it points to! Get rid of your delete statement in push and test that first (without pop). I haven't looked over your pop function, but I will leave that as an exercise for you to check for errors after you test pop().
-Dan8080