linked list not printing correctly? - c++

struct stack_struct
{
int number;
struct stack_struct *next_number;
};
stack_struct *mainStruct;
class stack_class
{
private:
struct stack_struct *head;
public:
stack_class();
//~stack_class();
void pushNumber(int number);
void popANumber();
void findNumber();
void clearStack();
void sizeFinder();
void printStack();
};
stack_struct *pointerFunc,*pointerFunc2,*pointerFunc3,*printPointer;
stack_class::stack_class()
{
head=NULL;
}
void stack_class::pushNumber(int numberFunc)
{
if(head==NULL)
{
head = new stack_struct;
head->number = numberFunc;
head->next_number = NULL;
pointerFunc2=head;
}
else
{
pointerFunc = new stack_struct;
pointerFunc->number=numberFunc;
pointerFunc->next_number=NULL;
head->next_number=pointerFunc;
head=pointerFunc;
}
}
void stack_class::printStack()
{
while(pointerFunc2)
{
cout<<pointerFunc2->number<<endl;
pointerFunc2=pointerFunc2->next_number;
}
}
int optionChosen;
int main()
{
stack_class mainClassStack;
do
{
cin>>optionChosen;
switch(optionChosen)
{
case 1:
{
int pushInt;
cout<<"\n\nEnter Number: ";
cin >> pushInt;
mainClassStack.pushNumber(pushInt);
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
case 4:
{
break;
}
case 5:
{
break;
}
case 6://print
{
mainClassStack.printStack();
break;
}
default:
{
break;
}
}
}while(optionChosen!=7);
return 0;
I am trying to implement a stack type of data list using dynamic memory (linked list). But when I try to prints the list, it only prints the list once, and if I try to reprint again using option 6, its like the list is gone. I went over the code twice but couldnt figure out what the problem was. Any suggestions?

The problem with your code is that after you print the stack, you aren't resetting pointerFunc2 to become head.
Either reset it correctly, or use a local variable inside your print function.
Here's a corrected version of your function:
void stack_class::printStack()
{
while (pointerFunc2)
{
cout << pointerFunc2->number << endl;
pointerFunc2 = pointerFunc2->next_number;
}
// reset pointerFunc2 so the next iteration
// can start at the head and print again.
pointerFunc2 = head;
}

The problem is when you print the stack the first time with this
pointerFunc2=pointerFunc2->next_number;
the pointerFunc2 becomes the last element after the first iteration. So that's why you think its gone. You should reset pointerFunc2 to point to the head node after being printed. So save it first, then after iterating thru the whole list, restore it, so that the next time you print the stack you will start with the head node.

The reason the second print does not work is that you are using a global variable instead of a local one:
stack_struct *pointerFunc2;
When you declare a variable outside a function or a class, it becomes global variable. Global variables survive function invocations, and retain the value that was last set into them. In order to be local, a variable needs to be declared inside printStack, initialized to the stack's head, and then discarded upon exiting the function. The same is true about pointerFunc.
The printPointer and pointerFunc3 variables are unused, and can be removed from the source code.

Related

Problem with display function inside circular queue

#include <stdio.h>
# define MAX 3
int queue[MAX]; // array declaration
int front=-1;
int rear=-1;
// function to insert an element in a circular queue
void enqueue(int element)
{
if(front==-1 && rear==-1) // condition to check queue is empty
{
front=0;
rear=0;
queue[rear]=element;
}
else if((rear+1)%MAX==front) // condition to check queue is full
{
printf("Queue is overflow..");
}
else
{
rear=(rear+1)%MAX; // rear is incremented
queue[rear]=element; // assigning a value to the queue at the rear position.
}
}
// function to delete the element from the queue
int dequeue()
{
if((front==-1) && (rear==-1)) // condition to check queue is empty
{
printf("\nQueue is underflow..");
}
else if(front==rear)
{
printf("\nThe dequeued element is %d", queue[front]);
front=-1;
rear=-1;
}
else
{
printf("\nThe dequeued element is %d", queue[front]);
front=(front+1)%MAX;
}
}
// function to display the elements of a queue
void display()
{
int i=front;
if(front==-1 && rear==-1)
{
printf("\n Queue is empty..");
}
else
{
printf("\nElements in a Queue are :");
while(i<=rear)
{
printf("%d,", queue[i]);
i=(i+1)%MAX;
}
}
}
int main()
{
int choice=1,x; // variables declaration
while(choice<4 && choice!=0) // while loop
{
printf("\nPress 1: Insert an element");
printf("\nPress 2: Delete an element");
printf("\nPress 3: Display the element");
printf("\nEnter your choice");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the element which is to be inserted");
scanf("%d", &x);
enqueue(x);
break;
case 2:
dequeue();
break;
case 3:
display();
}}
return 0;
}
I have problem with display function how can i print all element if rear can be in somecases less than front for example in this code i try to enqueue 3 elements 1,2,3 then dequeue two elements which i mean here 1,2 after that i try to enque two elements 1,2 again finaly when i try to display elements i get nothing so what is the perfect way to display queue elements
So... here's a working solution.
#include <stdio.h>
# define MAX 3
class CircularQueue
{
private:
int queue[MAX]; // array declaration
int front;
int rear;
public:
CircularQueue() :
front(-1),
rear(-1)
{ }
// function to insert an element in a circular queue
void enqueue(int element)
{
if(front==-1 && rear==-1) // condition to check queue is empty
{
front=0;
rear=0;
queue[rear]=element;
}
else if((rear+1)%MAX==front) // condition to check queue is full
{
printf("Queue is overflow..\n");
}
else
{
rear=(rear+1)%MAX; // rear is incremented
queue[rear]=element; // assigning a value to the queue at the rear position.
}
}
// function to delete the element from the queue
void dequeue()
{
if((front==-1) && (rear==-1)) // condition to check queue is empty
{
printf("Queue is underflow..\n");
}
else if(front==rear)
{
printf("The dequeued element is %d\n", queue[front]);
front=-1;
rear=-1;
}
else
{
printf("The dequeued element is %d\n", queue[front]);
front=(front+1)%MAX;
}
}
// function to display the elements of a queue
void display()
{
if(front==-1 && rear==-1)
printf("Queue is empty..\n");
else
{
printf("Elements in a Queue are: ");
int i=front;
do
{
if (i != front)
printf(",");
printf("%d", queue[i]);
i=(i+1)%MAX;
} while (i != (rear+1)%MAX);
printf("\n");
}
}
};
int main()
{
CircularQueue cq;
unsigned int choice=1; // variables declaration
while(choice<4 && choice!=0) // while loop
{
printf("Press 1: Insert an element\n");
printf("Press 2: Delete an element\n");
printf("Press 3: Display the element\n");
printf("Press any other number to exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Enter the element which is to be inserted: ");
int x;
scanf("%d", &x);
cq.enqueue(x);
break;
case 2:
cq.dequeue();
break;
case 3:
cq.display();
}
}
return 0;
}
I made a couple of changes to the output, see the positions of the \n. Its always good to give the next print statement a new line to write to if the current output is complete.
The biggest change, I put everything in a class. That way you don't have any global variables, which is to 99.999% a bad thing. Your code is very C like, so normally I would use std::cout as well and with std::vector you could easily make you buffer have arbitrary size.
Here's some output:
Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 1
Enter the element which is to be inserted: 2
Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 3
Elements in a Queue are: 2
Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 4
TL;DR version: The hard part of making a circular buffer is telling the full condition from the empty condition because they are both front == rear unless you take extra steps like tracking the size or maintaining a bool full; or preventing rear from catching up to front.
I like the latter approach because it makes for really simple code. I like writing simple code. You don't have to think as hard debugging it. You don't have to spend as much time writing it. You don't get bothered by the maintenance team supporting it. Simple code is only a problem when it's too simple and misses a case.
So I'm going for simple here.
Embedding comments where I feel it's appropriate because explanation is easier to understand when it's right up close to what it is explaining.
#include <stdio.h>
// made MAX one bigger
// If we waste a space in the queue the only time front can be the same as rear
// is if the queue is empty. No ambiguity. No special code for special cases or
// extra tracking variables to tell full from empty.
// All for the low, low price of one queue element.
# define MAX 4
// in full on c++ this would be constexpr int MAX = 4;
// In general avoid macros because they are really stupid. With a macro any
// token MAX will be replaced with 4 no matter how bad an idea it is. The
// resulting compiler errors get really weird.
// with a constexpr, the compiler will not substitute anything and will take
// context into account, giving much better diagnostics if you screw up
int queue[MAX]; // array declaration
// Don't comment the obvious stuff
// it just clutters up the code and makes you look... well..
// Hey, look! Dummy here needs a comment to rem'ber he's
// defining an array! HA HA HA HA HA!
// You've got better things to do than put up with smurf like that.
int front=0;
int rear=0;
// global variables suck. Because a global can be changed by anything at any
// time tracking errors is a pain in the neck. Every function could have
// unexpected side effects and needs to be examined while debugging.
// Plus because these variables are global and shared, you can only ever have
// ONE queue and EVERYBODY can use it.
// These variables and the queue-handling functions should be in a queue class,
// and there should be an instance of this class defined in main.
// helper functions to keep repetition down.
// Also a well-named helper makes what's happening brutally obvious to anyone
// reading the code
int advance(int pos)
{
return (pos+1)%MAX;
}
bool empty()
{
return front == rear;
}
bool full()
{
return front == advance(rear);
// because of the wasted space telling full from empty is dead easy
}
// function to insert an element in a circular queue
void enqueue(int element)
{
if(full()) // see? Much easer to read than if (front == (rear+1)%MAX)
// now we barely need to comment.
{
printf("Queue is overflow.\n");
}
else
{
queue[rear]=element;
rear = advance(rear);
}
}
// function to delete the element from the queue
void dequeue()
{
if(empty())
{
printf("Queue is underflow.\n");
}
else
{
printf("The dequeued element is %d\n", queue[front]);
front = advance(front);
}
}
// function to display the elements of a queue
void display()
{
if(empty())
{
printf("Queue is empty.");
}
else
{
int i = front;
printf("Elements in a Queue are :");
while(i!=rear)
{
printf("%d,", queue[i]);
i = advance(i);
}
}
printf("\n");
}
// test the logic in small chunks. Make sure the queue works perfectly before
// slapping in a menu system. If there's a bug, you don't have to ask if it's
// in the menu or in the queue because you're only testing one thing at a time
// when you know they both work separately, put 'em together and test again
// just to be on the safe side.
int main()
{
display();
enqueue(1);
display();
dequeue();
display();
enqueue(2);
display();
enqueue(3);
display();
enqueue(4);
display();
enqueue(5); // fail
display();
enqueue(6); // fail
display();
dequeue();
display();
dequeue();
display();
dequeue();
display();
dequeue(); // fail
display();
dequeue(); // fail
display();
return 0;
}

postfix evaluation , why is the push function not updating the top of stack variable?

when giving input "53+",it is pushing 5 and updates tos to 0 from '-1' but when the function is invoked for the second time, it pushes 3 but tos is still 0 , not 1. please help.
#include<iostream>
using namespace std;
int push(int tos, int x);
int pop(int tos);
int st[50];
int tos=-1;
int main()
{
char str[30];
int r,k,v1,v2,i;
cin>>str;
for(i=0;str[i]!='\0';i++)
{
if(str[i]!='*'&&str[i]!='-'&&str[i]!='+'&&str[i]!='/')
{
k=str[i]-'0';
push(tos,k);
}
else
{
if(tos==-1||tos==0)
cout<<"enter correct format";
else
{
v1=pop(tos);
v2=pop(tos);
switch(str[i])
{
case '*': r=v1*v2;
push(tos,r);
break;
case '+': r=v1+v2;
push(tos,r);
break;
case '-': r=v1-v2;
push(tos,r);
break;
case '/': r=v1/v2;
push(tos,r);
break;
default:
cout<<"invalid";
}
}
}
}
r=pop(tos);
cout<<endl<<r;
return 0;
}
int push(int tos, int x)
{
if (tos==50-1)
cout<<"overflow"<<endl;
else
{
tos++;
st[tos]=x;
cout<<endl<<"pushed"<<tos<<st[tos];
}
}
int pop(int tos)
{
int z;
if(tos==-1)
cout<<"underflow";
else
{
z=st[tos];
tos-=1;
}
return z;
}
when giving input "53+",it is pushing 5 and updates tos to 0 from '-1' but when the function is invoked for the second time, it pushes 3 but tos is still 0 , not 1.
Your push() and pop() functions receives tos by value, so any changes they make to tos are not reflected outside the functions.
One solution is to pass tos by reference, e.g.
int push(int &tos, int x)
{
// Any changes to tos are now reflected in the variable passed in.
...
}
The basic problem is that you have two variables called tos.
First is this global variable.
int tos=-1;
int main()
{
And then you have another variable called tos in the push function
int push(int tos, int x)
{
At the moment your code changes the local variable, but does not change the global variable, hence the confusion. Having local and global variables with the same name is asking for trouble. In this case I recommend that you remove the local variable. The st array is manipulated as a global, so it seems logical for the tos variable to be the same.
int push(int x)
{
You will have to change each call to push as well
push(tos,r);
becomes
push(r);
etc. etc.
Then you need to make exactly the same change to the pop function which has exactly the same problem.

Insertion and deletion in a stack using linked list

The program is about insertion and deletion in a stack using ling lists.The push works fine but there is problem in the deletion the pop() function has some
error. Every time i try to delete something it gives infinite error with underflow. ie. the top pointer is always null.
#include<iostream>
#include<stdlib.h>
#include<process.h>
using namespace std;
struct node
{
int info;
node *next;
}*top,*save,*newptr,*ptr;
node *create_new_node(int);
void push(node*);
void pop();
void display(node*);
int main()
{
top=NULL;
int inf;
char ch='y';
while(ch=='y'||ch=='Y')
{
newptr=new node;
cout<<"\nEnter the info to be added in the beginning of the stack\n";
cin>>inf;
if(newptr==NULL)
cout<<"\nCannot create new node.ABORTING!!\n";
else
{
newptr=create_new_node(inf);
cout<<"\nPress enter to continue\n";
system("pause");
}
push(newptr);
cout<<"\nthe info has been inserted in the stack\n";
cout<<"\nThe stack now is\n";
display(newptr);
cout<<"\ndo you wish to add more elements to the stack.\nIf yes then
press y or else press n\n";
cin>>ch;
if(ch=='n'||ch=='N')
{
cout<<"\ndo you to delete elements from the stack\n";
cout<,"\nIf yes then press d else press n\n";
cin>>ch;
if(ch=='d'||ch=='D')
{
while(ch=='d'||ch=='D')
{
pop();
cout<<"\npress d to delete more elements y to add more
elements and n to exit\n";
cin>>ch;
}
}
}
}
delete(ptr);
delete(newptr);
delete(top);
delete(save);
return 0;
}
node* create_new_node(int n)
{
ptr=new node;
ptr->info=n;
ptr->next=NULL;
return ptr;
}
void push(node *np)
{
if(top==NULL)
top=np;
else
{
save=top;
top=np;
np->next=save;
}
}
void pop()
{
if(top==NULL)
cout<<"underflow";
else
{
ptr=top;
top=top->next;
delete ptr;
}
}
void display(node *np)
{
while(np!=NULL)
{
cout<<np->info<<"->";
np=np->next;
}
}
There are multiple bugs in the shown code.
Your main bug:
while(ch=='d'||ch=='D')
{
pop();
cout<<"\npress d to delete more elements y to add more elements and n to exit\n";
}
At this point, when ch is 'd' or 'D' execution will enter the while loop, of course. A call to pop() is made, which removes the topmost element from the stack, prints a message, and repeats the while loop.
At this point your program will make an important discovery that ch is still either 'd' or 'D'. Nothing has changed its value. A computer program always does exactly what you tell it to do, unfortunately, instead of what you think you want it to do. No matter how hard you look here, you will never find any code here that ever changes the value of ch. It will remain at its current value forever. And so the while loop runs again. And again. And again. Nothing ever changes the value of ch, at this point, so you have an infinite loop.
Additionally, in your main:
newptr=new node;
This pointer's value is later compared to NULL; and if not ... it gets completely overwritten by
newptr=create_new_node(inf);
This accomplishes absolutely nothing, except leaking memory. This code appears to be leftover junk, and should be cleaned up after fixing the faulty while loop logic.

Reusing a Pointer to a Class in a Loop

In a program there is a pointer to a class object WordList *TheList;. WordList has subclasses WordDataList and WordDataDLinkList, so in a case statement we interpret which subclass to use and how to print out the information in the list. From what I understand in the specs, each case is supposed to declare TheList as a pointer of that type and use that, and then reclaim the memory at the end of the case so that it can be used in the next iteration of the loop. When I try something like:
while (true)
{
displayMenu();
cin>>selection;
switch(selection)
{
case '1':
TheList = new WordDataList;
TheList->parseIntoList(inf);
TheList->printIteratively();
delete TheList;
break;
case '2':
TheList = new WordDataList;
TheList->parseIntoList(inf);
TheList->printRecursively();
delete TheList;
break;
case '3':
TheList = new WordDataList;
TheList->parseIntoList(inf);
TheList->printPtrRecursively();
delete TheList;
break;
case '6':
cout<<"Goodbye"<<endl;
return 0;
default:
cout<<"I cannot understand "<<selection<<". Try again."<<endl;
break;
} // switch
} // while
Deleting the pointer makes it so after the first run through no data appears (Menu still comes up) and option 2 ends up seg faulting. I'm modifying code my professor gave, and when he had no delete call, and new WordDataList and parseIntoList before the loop it ran fine. Any suggestions?
Added:
I'm reinitializing TheList in each case because I'll be adding 4 and 5 that will use WordDataDLinkList. If it's a pointer to WordDataList from outside the case statement, how would I change it to WordDataDLinkList inside when I need to? My professor wrote WordDataList for us:
#include <sstream>
#include <iostream>
#include "WordDataList.h"
using namespace std;
WordDataList::WordDataList()
{ numWords=0; }
bool WordDataList::incMatch(string temp)
{ for(int i=0; i<numWords; i++) {
if (temp==TheWords[i].getWord()) {
TheWords[i].incCount();
return true;
}
}
return false;
}
void WordDataList::parseIntoList(ifstream &inf)
{ string temp;
while (inf >> temp)
if (!incMatch(temp) && numWords < 10) {
TheWords[numWords].setWord(temp);
TheWords[numWords++].setCount(1);
}
}
// Print the data iteratively
void WordDataList::printIteratively()
// void printObjectArrayIterator(WordData TheWords[], int numWords)
{
cout<<"--------------------------"<<endl;
cout<<"|Object Array Iterative|"<<endl;
cout<<"|Word Occurences |"<<endl;
cout<<"--------------------------"<<endl;
for(int i=0; i<numWords; i++)
cout<<" "<<TheWords[i]<<endl;
}
// Print the data recursively
void WordDataList::printRecursivelyWorker(int numWords)
//void printObjectArrayRecursive(WordData TheWords[], int numWords)
{if (numWords==1) {
cout<<"--------------------------"<<endl;
cout<<"|Object Array Recursive|"<<endl;
cout<<"|Word Occurences |"<<endl;
cout<<"--------------------------"<<endl;
cout<<" "<<TheWords[numWords-1]<<endl;
return;
}
printRecursivelyWorker(numWords-1);
cout<<" "<<TheWords[numWords-1]<<endl;
}
// Call worker function to print the data recursively
void WordDataList::printRecursively()
{ printRecursivelyWorker(numWords); }
// Print the data recursively with a pointer
void WordDataList::printPtrRecursivelyWorker(int numWords)
//void printObjectArrayPointerRecursive(WordData* TheWords, int numWords)
{if (!numWords)
{ cout<<"--------------------------"<<endl;
cout<<"|Object Array Pointer |"<<endl;
cout<<"|Word Occurences |"<<endl;
cout<<"--------------------------"<<endl;
return;
}
printPtrRecursivelyWorker(numWords-1);
cout<<" "<<*(TheWords+(numWords-1))<<endl;
}
// Call worker function to print the data recursively
void WordDataList::printPtrRecursively()
{ printPtrRecursivelyWorker(numWords); }
I think you are confused about something else. Why do you need to keep recreating the 'WordDataList' are the parse and print methods modifiying it?
If not, just create it once, and simply use the select to choose which print function to use if any.
I would also suggest putting each of the case execution statement sets into a closure, and adding some print outs or stepping through the debugger to see what is going on. Main guesses are that your 'new' is returning NULL such that you can't call its members properly OR destructor is bad.
Okay, so from what I can kindof tell: Options 1-3 should select a different subclass for your pointer TheList to hold. TheList is a pointer to your base class so that's good. What I think you need to do is new the appropriate subclass in each switch statement. I.E.
case '1': TheList = new WordDataDLinkList();
EDIT: if you intend to call a different version of each member function based off the classtype you are currently using, as in WordDataDLinkList::parseIntoList(inf), instead of WordDataList::parseIntoList(inf), try reading up on polymorphism

Insertion error in Binary Search tree

void BST::insert(string word)
{
insert(buildWord(word),root);
}
//Above is the gateway insertion function that calls the function below
//in order to build the Node, then passes the Node into the insert function
//below that
Node* BST::buildWord(string word)
{
Node* newWord = new Node;
newWord->left = NULL;
newWord->right = NULL;
newWord->word = normalizeString(word);
return newWord;
}
//The normalizeString() returns a lowercase string, no problems there
void BST::insert(Node* newWord,Node* wordPntr)
{
if(wordPntr == NULL)
{
cout << "wordPntr is NULL" << endl;
wordPntr = newWord;
cout << wordPntr->word << endl;
}
else if(newWord->word.compare(wordPntr->word) < 0)
{
cout << "word alphabetized before" << endl;
insert(newWord,wordPntr->left);
}
else if(newWord->word.compare(wordPntr->word) > 0)
{
cout << "word alphabetized after" << endl;
insert(newWord, wordPntr->right);
}
else
{
delete newWord;
}
}
So my problem is this: I call the gateway insert() externally (also no problems with the inflow of data) and every time it tells me that the root, or the initial Node* is NULL. But that should only be the case before the first insert. Each time the function is called, it sticks the newWord right at the root.
To clarify: These functions are part of the BST class, and root is a Node* and a private member of BST.h
It's possible it is quite obvious, and I have just been staring too long. Any help would be appreciated.
Also, this is a school-assigned project.
Best
Like user946850 says, the variable wordPntr is a local variable, if you change it to point to something else it will not be reflected in the calling function.
There are two ways of fixing this:
The old C way, by using a pointer to a pointer:
void BST::insert(Node *newWord, Node **wordPntr)
{
// ...
*wordPntr = newWord;
// ...
}
You call it this way:
some_object.insert(newWord, &rootPntr);
Using C++ references:
void BST::insert(Node *newWord, Node *&wordPntr)
{
// Nothing here or in the caller changes
// ...
}
To help you understand this better, I suggest you read more about scope and lifetime of variables.
The assignment wordPntr = newWord; is local to the insert function, it should somehow set the root of the tree in this case.