Implementing Queue Using LinkedList [duplicate] - c++

This question already has answers here:
How come a non-const reference cannot bind to a temporary object?
(11 answers)
Closed 5 years ago.
So, i'm attempting to implement this Queue using my LinkedList that I previously created. I've provided the code for both classes. Currently, I'm work on attempting to get pop and push to work without changing the function prototype (it's for an assignment).
When looking specifically at peek(I haven't quite finished pop), for some reason, when I run the code, I get strange pointer error.
Error C2440 'default argument': cannot convert from 'int' to 'int &'
I'm not sure exactly what that means in this context. The function is suppose to look at the object at the top of the queue without removing it, and return true or false based upon if the operation was successful or not.
Here is the info for QUEUE.
#ifndef _QUEUE_H
#define _QUEUE_H 1
#include "QueueInterface.h"
#include "LinkedList.hpp"
template <typename T>
class Queue : public QueueInterface<T>
{
protected:
LinkedList<T> _list;
int count;
public:
unsigned size() const
{
return count;
}
bool push(const T& val = T{})
{
_list.push(val);
count++;
return true;
}
bool empty() const
{
return _list.isEmpty();
}
bool pop(T& val = T{})
{
return true;
}
bool peek(T& val = T{}) const
{
std::cout << _list.last() << std::endl;
return true;
}
void clear()
{
_list.clear();
}
int search(const T& target = T{}) const
{
return _list.search(target);
}
//
// Internal consistency check
//
void toString()
{
_list.toString();
}
public:
virtual bool check() const
{
return _list.check();
}
};
#endif
Here is Linked List.
#ifndef _LINKED_LIST_GUARD
#define _LINKED_LIST_GUARD 1
#include <iostream>
#include "ListInterface.h"
template <typename T>
class LinkedList : public ListInterface<T>
{
public:
int count = 0;
LinkedList()
{
_head = new Node;
_tail = new Node;
_head->_next = _tail;
}
private:
//
// Private node class to facilitate linked list
//
class Node
{
public:
T _data;
Node* _next;
// Constructor: default
Node(T d = T{}, Node* n = nullptr) : _data(d), _next(n) {}
~Node() { _next = nullptr; }
};
//
// Prevent copying and assigning
//
LinkedList(const LinkedList& rhs) {}
const LinkedList& operator=(const LinkedList& rhs) {}
public:
//
// LinkedList instance variables; we use dummy head and tail nodes in this implementation
unsigned _size;
Node* _head;
Node* _tail;
// Returns the first element in the list
T& first() const
{
return _head->_next->_data;
}
// Adds an item to the LEFT side of the linked list
void push(const T& x)
{
// Creates a new node with the user input data.
Node* current = new Node;
current->_data = x;
current->_next = _head->_next;
_head->_next = current;
count++;
}
// ASK ABOUT
T& operator[](unsigned n)
{
int position = 1;
if (n != count)
{
throw("Invalid Position");
}
for (Node* current = _head->_next; current != _tail; current = current->_next, position++)
{
if (position == n)
{
return current -> _data;
}
}
}
void clear()
{
do
{
pop();
} while (count != 0);
}
bool contains(const T& target) const
{
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
if (current->_data == target)
return true;
}
return false;
}
bool pop()
{
if (_head->_next == _tail)
{
std::cout << "unable to pop, list is empty";
return false;
}
if (_head->_next != _tail)
{
Node* deleteNode = _head->_next;
_head->_next = _head->_next->_next;
delete deleteNode;
count--;
return true;
}
return false;
}
T& last() const
{
if (_head->_next == _tail)
{
std::cout << "LIST IS EMPTY" << std::endl;
}
if (_head->_next != _tail)
{
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
if (current->_next == _tail)
return current->_data;
}
}
}
// ASK ABOUT
int search(const T& target = T{}) const
{
int position = 1;
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
if (current->_data == target)
{
return position;
}
else position++;
}
return -1;
}
bool isEmpty() const
{
if (_head->_next == _tail)
{
return true;
}
return false;
}
unsigned size() const
{
return count;
}
bool remove(const T& target)
{
Node* deleteNode = nullptr;
Node* trailer = _head;
Node* current = _head->_next;
while (current != _tail && current-> _data != target)
{
trailer = current;
current = current->_next;
}
if (current->_data == target)
{
deleteNode = current;
current = current->_next;
trailer->_next = current;
delete deleteNode;
count--;
return true;
}
else
std::cout << "unable to remove, item not in list" << std::endl;
return false;
}
//FOR TESTING
void toString()
{
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
std::cout << current->_data << std::endl;
}
}
//
// Internal consistency check
//
public:
virtual bool check() const
{
bool sizeConsistent = isSizeConsistent();
bool headTailConsistent = isEndConsistent();
if (!sizeConsistent) std::cerr << "Size inconsistent" << std::endl;
if (!headTailConsistent) std::cerr << "Head / Tail inconsistent" << std::endl;
return sizeConsistent && headTailConsistent;
}
//
// Stated size is accurate to the entire list
//
bool isSizeConsistent() const
{
int count = 0;
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
count++;
}
return size() == count;
}
//
// Checks that the head and tail are defaulted properly and the
// respective next pointers are appropriate.
//
bool isEndConsistent() const
{
if (_head->_data != T{}) return false;
if (_tail->_data != T{}) return false;
if (_head->_next == nullptr) return false;
if (_tail->_next != nullptr) return false;
if (isEmpty() && _head->_next != _tail) return false;
if (!isEmpty() && _head->_next == _tail) return false;
return true;
}
};
#endif
And finally, here is my main. The top portion is to test the functionality for LinkedList. The bottom portion is what I was working with to test queue.
#include "Queue.hpp"
#include "LinkedList.hpp"
#include <string>
#include <iostream>
int main()
{
LinkedList<int> list;
LinkedList<int> listEmpty;
Queue<int> list2;
list.push(1);
list.push(2);
list.push(3);
list.push(4);
list.push(5);
list.remove(1);
std::cout << "List contains 4? " << list.contains(4) << std::endl;
std::cout << "List empty? " << list.isEmpty() << std::endl;
std::cout << "List size: " << list.size() << std::endl;
std::cout << "Last in list? " << list.last() << std::endl;
std::cout << "What is in position 4? " << list[4] << std::endl;
std::cout << "Search " << list.search(10) << std::endl;
//std::cout << "3 is in position " << list.search() << std::endl;
std::cout << " " << std::endl;
list.toString();
list.clear();
std::cout << "///////////////////////////////////////////////////////////////////////////////" << std::endl;
list.push(4);
list.toString();
std::cout << "///////////////////////////////////////////////////////////////////////////////" << std::endl;
std::cout << "QUEUE STUFF" << std::endl;
std::cout << "///////////////////////////////////////////////////////////////////////////////" << std::endl;
list2.push(1);
list2.push(2);
list2.push(6);
list2.push(3);
list2.push(4);
list2.push(5);
std::cout << "Queue empty? " << list2.empty() << std::endl;
std::cout << "Queue size: " << list2.size() << std::endl;
std::cout << "First in Queue? " << list2.peek() << std::endl;
std::cout << "What position is 6 in? : " << list2.search(6) << std::endl;
list2.toString();
std::cout << " " << std::endl;
system("pause");
I guess my question is this, what steps can I take to go about fixing this particular function?
Thanks in advance!

The problem with your code is that peek, as you said, should not modify the Queue and neither take any parameter because it merely looks at the top of the structure and returns either true or false.
So a solution is to remove the parameter in peak as follows and everything compiles and runs.
bool peek() const
{
std::cout << _list.last() << std::endl;
return true;
}
Specifically, the error you get is because you cannot assign to a non-const lvalue reference an rvalue reference.
This is exactly what you are doing in T& val = T{}. T{} is an rvalue and clearly, val is a non-const reference to T.
You can try using bool peek(const T& val = T{}) const and see by yourself that everything compiles fine.

Related

Why do the values change after leaving the function and why do I get a segmentation fault?

I have this homework for my C++ class. I have to implement a list class, where I can add from the front or the back. I have implemented it, but there is a big problem.
collectiontest.cpp
#include "list.hpp"
#include <iostream>
int main(void) {
std::cout << "--- Test List ---" << std::endl;
List<int> l;
std::cout << l;
l.add(2);
l.add_front(3);
l.add(1);
std::cout << l;
std::cout << "remove_front: " << l.remove_front() << std::endl;
std::cout << "remove_front: " << l.remove_front() << std::endl;
l.add(5);
std::cout << l;
std::cout << "Contains 5? " << l.contains(5) << std::endl;
std::cout << "remove_back: " << std::endl;
std::cout << l.remove() << std::endl;
std::cout << "remove_back: " << l.remove() << std::endl;
std::cout << l;
return 0;
}
list.hpp
#pragma once
#include "collection.hpp"
#include "node.hpp"
#include <iostream>
#include <string>
template <typename T>
class List : public Collection<T> {
private:
Node<T>* first;
Node<T>* last;
public:
~List() {
if (first != nullptr) {
}
}
void add_front(T value) {
if (first == nullptr) {
std::cout << "First element front" << std::endl;
Node<T> temp(value, nullptr, nullptr);
first = &temp;
last = &temp;
}
else {
if (first == last) {
std::cout << "First and last are same! front-> " << first << "-" << last << std::endl;
Node<T> temp(value, last, nullptr);
last->previous = &temp;
first = &temp;
std::cout << first << "-" << last << std::endl;
}
else {
Node<T> temp(value, first, nullptr);
first->previous = &temp;
first = &temp;
}
}
}
void add(T value) override {
std::cout << "LOL" << std::endl;
if (first == nullptr) {
std::cout << "First element add" << std::endl;
Node<T> temp(value, nullptr, nullptr);
first = &temp;
last = first;
std::cout << "end of add first item" << std::endl;
}
else {
if (first == last) {
std::cout << "First and last are same! add-> " << first << "-" << last << std::endl;
Node<T> temp(value, nullptr, first);
first->next = &temp;
last = &temp;
}
else {
Node<T> temp(value, nullptr, last);
last->next = &temp;
last = &temp;
}
}
}
T remove_front() {
if (first != nullptr) {
T te = first->content;
Node<T>* temp = first;
first = first->next;
return te;
}
return NULL;
}
T remove() override {
if (last != nullptr) {
Node<T>* temp = last;
T te = last->content;
last = last->previous;
last->next = nullptr;
return te;
}
return NULL;
}
bool isEmpty() override {
return (first == nullptr);
}
bool contains(T value) override {
Node<T>* temp = first;
while (temp != nullptr) {
if (temp->content == value) return true;
temp = temp->next;
}
return false;
}
void clear() override {
Node<T>* temp = first->next;
while (temp != nullptr) {
first = temp;
temp = temp->next;
}
}
int getSize() override {
int counter = 0;
Node<T>* temp = first;
while (temp != nullptr) {
counter++;
temp = temp->next;
}
return counter;
}
Node<int>* getFirst() const {
return first;
}
Node<int>* getLast() const {
return last;
}
friend std::ostream& operator<<(std::ostream& os, const List<int>& l);
};
std::ostream& operator<<(std::ostream& stream, const List<int>& l) {
std::cout << "Output called" << std::endl;
Node<int>* temp = l.getLast();
while (temp != nullptr) {
std::cout << "Schleife betreten" << std::endl;
stream << temp->content << " ";
temp = temp->previous;
}
stream << std::endl;
return stream;
}
collection.hpp
#pragma once
template <typename T>
class Collection {
virtual void add(T value) = 0;
virtual int remove() = 0;
virtual bool isEmpty() = 0;
virtual bool contains(T obj) = 0;
virtual void clear() = 0;
virtual int getSize() = 0;
};
node.hpp
#pragma once
template <typename T>
class Node {
public:
Node<T>* next;
Node<T>* previous;
T content;
Node(T value, Node<T>* next, Node<T>* previous) {
content = value;
this->next = next;
this->previous = previous;
}
~Node() {
}
};
I have looked over it several times, but I get the same error.
I debugged my program with Visual Studio, and what happens is collectortest.cpp creates the list and adds the first value with the add() function. In the debugger, I see how the temp node is created, how first is set to the address of temp, and how last is set to the same address. So, when we reach the line where "end of add first item" is supposed to be printed to the console, the variables changes, why??
You can see in this image how the variables all have appropriate values:
Before the output:
But then, when I leave the breakpoint I set at "end of add first item", this happens:
After the output:
There must be something I don't see, because this makes literally no sense. I have looked everywhere, maybe it is just something really dumb, but I am really at my limits here.
Can one of you help and explain what the problem is?
I tried to execute my program and create the nodes appropriately, but I get a strange error in my memory.
From #Wyck:
Node<T> temp(value, nullptr, nullptr);
first = &temp;
You're using a pointer to something that is allocated on the stack and will be destroyed/invalid when it goes out of scope whether you have taken note of the address it used to be at or not.
From #user4581301:
Node<T> temp(value, nullptr, nullptr);
first = &temp;
is one of the increasingly rare times you want to use new.
first = new Node<T>(value, nullptr, nullptr);
From #TedLyngmo:
For the problem #Wyck mentioned, you need to allocate and release memory dynamically using new/delete.
These were the answers posted as comments to the question. My Nodes always got destroyed because they were out of scope. I needed to use new so they got stored in the heap and weren't automatically destroyed if they went out of scope.
Edit: I can't choose my own answer as correct for 2 days, so the question sadly stays open.

How to implement iterator design pattern on C++?

I'm curious about how to implement the iterator pattern the way STL does in a stack ADT.
#include <iostream>
#include <vector>
int main() {
std::vector<char> v = { 'a', 'b', 'c', 'd', 'e', 'f'};
std::vector<char>::iterator it = v.begin();
while(it != v.end()) {
std::cout << *it << "->";
++it;
}
std::cout << "\n";
return 0;
}
Output
a->b->c->d->e->f->
so far I have implemented the following code
#include <iostream>
#include <memory>
template<class T>class Node {
private:
T data = 0;
std::shared_ptr<Node<T>> next_node = nullptr;
public:
Node(T data = 0, std::shared_ptr<Node<T>> next_node = nullptr)
: data(data), next_node(next_node)
{
std::cout << "created node[" << data << "]\n";
}
~Node() {
std::cout << "deleted node[" << data << "]\n";
}
// getters and setters
T getData() const {
return this->data;
}
std::shared_ptr<Node<T>> getNextNode() const {
return this->next_node;
}
void setData(T value) {
this->data = value;
}
void setNextNode(std::shared_ptr<Node<T>> node) {
this->next_node = node;
}
};
template<class T>std::ostream& operator<<(std::ostream& o, const std::shared_ptr<Node<T>> node) {
return o << "node["<< node->getData() <<"]-> ";
}
template<class T>class Stack {
private:
std::shared_ptr<Node<T>> top = nullptr;
public:
Stack()
: top(nullptr)
{ /* empty */ }
~Stack() { /* empty */ }
void push(T value) {
if(!top) {
top = std::shared_ptr<Node<T>> (new Node<T>(value));
} else {
top = std::shared_ptr<Node<T>> (new Node<T>(value, top));
}
}
void display() {
if(!top) {
std::cout << "display::The stack is empty.\n";
} else {
std::shared_ptr<Node<T>> p = top;
while(p) {
std::cout << p;
p = p->getNextNode();
}
std::cout << "\n";
}
}
class Iterator {
private:
std::shared_ptr<Node<T>> node;
public:
Iterator(std::shared_ptr<Node<T>> node)
: node(node)
{ /* empty */ }
bool hasMore() {
return node->getNextNode() != nullptr;
}
Iterator getNext() {
return Iterator(node->getNextNode());
}
int getData() {
return node->getData();
}
};
Iterator begin() const {
return Iterator(top);
}
Iterator getIterator() {
Iterator it = Iterator(top);
return it;
}
};
int main() {
Stack<char> stack;
for(char i = 'a'; i < 'f'; ++i) {
stack.push(i);
}
Stack<char>::Iterator it = stack.begin();
while(it.hasMore()) {
std::cout << it.getData() << "->";
it = it.getNext();
}
std::cout << "\n";
return 0;
}
Output:
created node[a]
created node[b]
created node[c]
created node[d]
created node[e]
101->100->99->98->
deleted node[e]
deleted node[d]
deleted node[c]
deleted node[b]
deleted node[a]
My question is how to implement nested template detection for the Iterator class, as you can see the expected output is a char type and I am getting integers.
Can someone help me understand how this is implemented in the STL and how it could be implemented in an ADT?
thanks!!!
Thanks for the comments I be able to fix the problem I was returning the wrong data type on int getData() { return node->getData(); } I just change the int type for T type and everithing works ok!
also change the hasMore method for bool hasMore() { return node != nullptr; }
#include <iostream>
#include <memory>
template<class T>class Node {
private:
T data = 0;
std::shared_ptr<Node<T>> next_node = nullptr;
public:
Node(T data = 0, std::shared_ptr<Node<T>> next_node = nullptr)
: data(data), next_node(next_node)
{
std::cout << "created node[" << data << "]\n";
}
~Node() {
std::cout << "deleted node[" << data << "]\n";
}
// getters and setters
T getData() const {
return this->data;
}
std::shared_ptr<Node<T>> getNextNode() const {
return this->next_node;
}
void setData(T value) {
this->data = value;
}
void setNextNode(std::shared_ptr<Node<T>> node) {
this->next_node = node;
}
};
template<class T>std::ostream& operator<<(std::ostream& o, const std::shared_ptr<Node<T>> node) {
return o << "node["<< node->getData() <<"]-> ";
}
template<class T>class Stack {
private:
std::shared_ptr<Node<T>> top = nullptr;
public:
Stack()
: top(nullptr)
{ /* empty */ }
~Stack() { /* empty */ }
void push(T value) {
if(!top) {
top = std::shared_ptr<Node<T>> (new Node<T>(value));
} else {
top = std::shared_ptr<Node<T>> (new Node<T>(value, top));
}
}
void display() {
if(!top) {
std::cout << "display::The stack is empty.\n";
} else {
std::shared_ptr<Node<T>> p = top;
while(p) {
std::cout << p;
p = p->getNextNode();
}
std::cout << "\n";
}
}
class Iterator {
private:
std::shared_ptr<Node<T>> node;
public:
Iterator(std::shared_ptr<Node<T>> node)
: node(node)
{ /* empty */ }
bool hasMore() {
return node != nullptr;
}
Iterator getNext() {
return Iterator(node->getNextNode());
}
T getData() {
return node->getData();
}
};
Iterator begin() const {
return Iterator(top);
}
Iterator getIterator() {
Iterator it = Iterator(top);
return it;
}
};
int main() {
Stack<char> stack;
for(char i = 'a'; i < 'f'; ++i) {
stack.push(i);
}
Stack<char>::Iterator it = stack.begin();
while(it.hasMore()) {
std::cout << it.getData() << "->";
it = it.getNext();
}
std::cout << "\n";
return 0;
}
Output
created node[a]
created node[b]
created node[c]
created node[d]
created node[e]
e->d->c->b->a->
deleted node[e]
deleted node[d]
deleted node[c]
deleted node[b]
deleted node[a]

Insert function recreates root node

I'm trying to create a non-recursive insert() function. The only example I have in the book is a recursive one and I'm trying to convert it. Just so you have an idea of what I'm trying to accomplish and why I'll include the instructions.
Write a class for implementing a simple binary search tree capable of storing numbers. The class should have member functions:
void insert(double x)
bool search(double x)
void inorder(vector <double> & v)
The insert function should not use recursion directly or indirectly by calling a recursive function.
There is more, but I think this gives the idea behind what I'm asking about. As of now the function just keep recreating the root node. Here is what I have.
#include "stdafx.h"
#include <iostream>
#include <vector>
class BinaryTree {
private:
struct TreeNode {
double value;
TreeNode *left;
TreeNode *right;
TreeNode(double value1,
TreeNode *left1 = nullptr,
TreeNode *right1 = nullptr) {
value = value1;
left = left1;
right = right1;
}
};
TreeNode *root; //pointer to the root of the tree
bool search(double x, TreeNode *t) {
while (t) {
std::cout << "running through t." << std::endl;
if (t->value == x) {
return true;
}
else if (x < t->value) {
std::cout << "wasn't found, moving left." << std::endl;
search(x, t->left);
}
else {
std::cout << "wasn't found, moving right." << std::endl;
search(x, t->right);
}
}
std::cout << "wasn't found." << std::endl;
return false;
}
public:
std::vector<TreeNode> v;
BinaryTree() {
root = nullptr;
}
void insert(double x) {
TreeNode *tree = root;
if (!tree) {
std::cout << "Creating tree." << x << std::endl;
root = new TreeNode(x);
return;
}
while (tree) {
std::cout << "Adding next value." << std::endl;
if (tree->value == x) return;
if (x < tree->value) {
tree = tree->left;
tree->value = x;
}
else {
tree = tree->right;
tree->value = x;
}
}
}
bool search(double x) {
return search(x, root);
}
/*void inOrder(TreeNode *v) const {
while (root != nullptr) {
inOrder(root->left);
v.push_back(root->value);
inOrder(root->right);
v.push_back(root->value);
}
}*/
};
int main() {
BinaryTree t;
std::cout << "Inserting the numbers 5, 8, 3, 12, and 9." << std::endl;
t.insert(5);
t.insert(8);
t.insert(3);
t.insert(12);
t.insert(9);
std::cout << "Looking for 12 in tree." << std::endl;
if (t.search(12)) {
std::cout << "12 was found." << std::endl;
}
std::cout << "Here are the numbers in order." << std::endl;
return 0;
}
You have to add one more level of dereference if you want your code to work. And of course create the new node at the end of the function. The following code should work:
void insert(double x) {
TreeNode **tree = &root;
while (*tree) {
std::cout << "Adding next value." << std::endl;
if ((*tree)->value == x) return;
if (x < (*tree)->value) {
tree = &(*tree)->left;
} else {
tree = &(*tree)->right;
}
}
if (!(*tree)) {
std::cout << "Creating tree." << x << std::endl;
*tree = new TreeNode(x);
return;
}
}
And your search method should looks like:
bool search(double x) {
TreeNode *node = root;
while (node) {
if (node->value == x) {
return true;
} else if (x < node->value) {
node = node->left;
} else {
node = node->right;
}
}
std::cout << "wasn't found." << std::endl;
return false;
}
Result of your main function, with my code:
Inserting the numbers 5, 8, 3, 12, and 9.
Creating tree.5
Adding next value.
Creating tree.8
Adding next value.
Creating tree.3
Adding next value.
Adding next value.
Creating tree.12
Adding next value.
Adding next value.
Adding next value.
Creating tree.9
Looking for 12 in tree.
12 was found.

Car Wash Queue Issue

I'm working on a variation of the "Car Queue" or "Car Wash" problem in which I have to input how long a car will take to wash, the odds of a car entering the queue for the wash at any given moment, and then receive as output how many cars were washed, how many cars were left in the queue at the end of the day, and how much total waiting time there was. I'm still very new to c++, and have only been using it extensively for the last few months. Its very possible there's an error with my queue implementation code that I didn't catch, but I believe the error is in the main. Currently, I added outputs for every loop, so I could watch the code run, and follow it. It appeared to be accepting a car, and then immediately finishing the wash on it. Then, when no car is present, it simply alternates between a washing and waiting loop. Any help would be greatly appreciated.
#include <assert>
#include <iostream>
#include <fstream>
#include <ostream>
#include <ctime>
#include <cstdlib>
using namespace std;
class Node
{
private:
int item;
Node * next;
public:
Node ();
Node (const int& anItem);
Node (const int& anItem, Node * nextNodePtr);
void setItem (const int& anItem);
void setNext (Node * nextNodePtr);
int getItem ();
Node* getNext();
};
class LinkedQueue
{
private:
Node* backPtr;
Node* frontPtr;
public:
bool isEmpty();
bool enqueue(int& newEntry);
bool dequeue();
int peekFront() const;
LinkedQueue();
~LinkedQueue();
LinkedQueue(const LinkedQueue& aQueue);
};
int main ()
{
srand(1);
int timeForWash;
int minute;
int timeEnteredQueue;
int carsWashed;
int totalQueueMin;
int timeLeftOnCar;
int probOfArrival;
int carsInQueue = 0;
LinkedQueue carQueue;
cout << "Enter time to wash one car:" << endl;
cin >> timeForWash;
cout << endl;
cout << "Enter probability of arrival per minute" << endl;
cin >> probOfArrival;
carsWashed = 0;
totalQueueMin = 0;
timeLeftOnCar = 0;
for (minute = 1; minute <= 20; ++minute)
{
if (rand()%100 <= probOfArrival)
{
carQueue.enqueue(minute);
carsInQueue++;
cout << "Queued" << endl;
}
if ((timeLeftOnCar == 0) && ( !carQueue.isEmpty()))
{
timeEnteredQueue = carQueue.peekFront();
carQueue.dequeue();
totalQueueMin = totalQueueMin + (minute - timeEnteredQueue);
++carsWashed;
carsInQueue--;
timeLeftOnCar = timeForWash;
cout << "Finish" << endl;
}
if (timeLeftOnCar =! 0)
{
timeLeftOnCar -= 1;
cout << "Washing" << endl;
}
if ((timeLeftOnCar == 0) && ( carQueue.isEmpty()))
{
cout << "Waiting" << endl;
}
}
cout << carsWashed << endl;
cout << totalQueueMin << endl;
cout << carsInQueue << endl;
system("pause");
return(0);
};
//Implementation
Node:: Node() : next (nullptr)
{
} // default
Node:: Node (const int& anItem) : item(anItem), next(nullptr)
{
}
Node:: Node (const int& anItem, Node * nextNodePtr) : item(anItem), next(nextNodePtr)
{
}
void Node:: setItem (const int& anItem)
{
item = anItem;
}
void Node:: setNext (Node * nextNodePtr)
{
next = nextNodePtr;
}
int Node:: getItem ()
{
return item;
}
Node * Node:: getNext ()
{
return next;
}
bool LinkedQueue::enqueue(int& newEntry)
{
Node* newNodePtr = new Node(newEntry);
//Insert the new node
if (isEmpty())
frontPtr = newNodePtr; // The queue was empty
else
backPtr->setNext(newNodePtr); // The queue was not empty
backPtr = newNodePtr; // New node is at back
return true;
} // end enqueue
bool LinkedQueue::dequeue()
{
bool result = false;
if (!isEmpty())
{
// Queue is not empty; remove front
Node* nodeToDeletePtr = frontPtr;
if (frontPtr == backPtr)
{ // Special case: one node in queue
frontPtr = nullptr;
backPtr = nullptr;
}
else
frontPtr = frontPtr->getNext();
// Return deleted node to system
nodeToDeletePtr->setNext( nullptr);
delete nodeToDeletePtr;
nodeToDeletePtr = nullptr;
result = true;
} // end if
return result;
} // end dequeue
bool LinkedQueue:: isEmpty()
{
return (frontPtr == nullptr );
}
int LinkedQueue:: peekFront() const
{
return frontPtr->getItem();
}
LinkedQueue::LinkedQueue()
{
frontPtr = nullptr;
backPtr = nullptr;
}
LinkedQueue::LinkedQueue( const LinkedQueue& aQueue) :
frontPtr(aQueue.frontPtr)
{
} // end copy constructor
LinkedQueue::~LinkedQueue()
{
} // end destructor
timeLeftOnCar =! 0 is the same as timeLeftOnCar = !0, which is timeLeftOnCar = 1, which is always true.
You wanttimeLeftOnCar != 0 or timeLeftOnCar > 0.

Error "System.AccessViolationException" show binary tree after cut visualc++

I have a problem with this Binary Search Tree.
After that i cut a leave, if I try to show the tree VisualStudio answer me this message
An unhandled exception of type 'System.AccessViolationException' occurred in ABR1.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
It's more that 3 days that i try to understand could someone help me???
// ABR1.cpp : main project file.
#include "stdafx.h"
#include <iostream>
using namespace System;
using namespace std;
template <class T>
class ABR{
private:
struct Leaf{
T value;
struct Leaf *DX; //
struct Leaf *SX; //
};
Leaf *root;
public:
//constructors
ABR() { root = NULL; }
//destructor
//~ABR();
void appendLeaf(T);
bool cutLeaf(T);
bool isInTree(T) const;
Leaf* findLeaf(T) const;
void showTreeInOrder() const { showTreeInOrder(root); }
void showTreeInOrder(Leaf *) const;
void showTreePreOrder() const { showTreePreOrder(root); }
void showTreePreOrder(Leaf *) const;
};
template <class T>
void ABR<T>::appendLeaf(T newValue){
if (isInTree(newValue)){
cout << "The value is just present..." << endl;
return;
}
Leaf *newLeaf; // To point to a new leaf
Leaf *ptrLeaf; // To move in the tree
// Allocate the necessary memory
newLeaf = new Leaf; //generate the new leaf
newLeaf-> value = newValue;
newLeaf-> DX = NULL;
newLeaf-> SX = NULL;
if(!root) //if is the first leaf
root = newLeaf;
else{
ptrLeaf = root;
//cout<<ptrLeaf->value<<ptrLeaf->SX<<ptrLeaf->DX<<endl;
while (ptrLeaf != NULL){
//cout << ptrLeaf->value <<"\t";
if (ptrLeaf->value < newValue){
if (ptrLeaf->DX == NULL){
ptrLeaf->DX = newLeaf;
return;
}
else
ptrLeaf = ptrLeaf->DX;
}
else{
if(ptrLeaf->SX == NULL){
ptrLeaf->SX = newLeaf;
return;
}
else
ptrLeaf = ptrLeaf->SX;
}
}
}
}
template <class T>
bool ABR<T>::isInTree(T toFind) const{
Leaf *ptrLeaf;
ptrLeaf = root;
while (ptrLeaf){
if (ptrLeaf->value == toFind)
return true;
else{
if (ptrLeaf->value < toFind)
ptrLeaf = ptrLeaf->DX;
else
ptrLeaf = ptrLeaf->SX;
}
}
return false;
}
template <class T>
typename ABR<T>::Leaf * ABR<T>::findLeaf(T toFind) const
{
Leaf *ptr;
ptr = root;
while(ptr != NULL)
{
//cout << ptr->value << "#" << endl;
if (toFind == ptr->value){
//cout << "Trovato";
return ptr;
}
else if (ptr->value < toFind)
ptr = ptr->DX;
else
ptr = ptr->SX;
} cout << "Element don't find" << endl;
return NULL;
}
template <class T>
void ABR<T>::showTreeInOrder(Leaf *ptr) const
{
if(ptr != NULL)
{
showTreeInOrder(ptr->SX);
cout << ptr->value << endl;
showTreeInOrder(ptr->DX);
}
}
template <class T>
void ABR<T>::showTreePreOrder(Leaf *ptr) const
{
if(ptr != NULL)
{
showTreePreOrder(ptr->DX);
cout << ptr->value << endl;
showTreePreOrder(ptr->SX);
}
}
template <class T>
bool ABR<T>::cutLeaf(T toCut)
{
Leaf *Leafptr, *tempLeafptr;
Leafptr = findLeaf(toCut);
if (Leafptr == NULL)
{
cout << "The element is not present..." << endl;
return false;
}
else if (Leafptr->DX == NULL)
{
tempLeafptr = Leafptr;
Leafptr = Leafptr->SX;
delete tempLeafptr;
return true;
}
else if (Leafptr->SX == NULL)
{
tempLeafptr = Leafptr;
Leafptr = Leafptr->DX;
delete tempLeafptr;
return true;
}
else
{
tempLeafptr = Leafptr->DX;
while (tempLeafptr->SX)
tempLeafptr = tempLeafptr->SX;
tempLeafptr->DX = Leafptr->SX;
tempLeafptr = Leafptr;
Leafptr = Leafptr->DX;
delete tempLeafptr;
return true;
}
}
int main(){
ABR<int> albero;
for(int a = 0.0; a < 100.0; a+= 3)
albero.appendLeaf(a);
albero.appendLeaf(1000);
albero.appendLeaf(1001);
albero.showTreePreOrder();
int b = 75;
albero.cutLeaf(b);
albero.showTreePreOrder(); //ERROR
//albero.showTreeInOrder();//SAME ERROR
system("PAUSE");
return 0;
}
You're recursing in showTreePreOrder and encountering a stack overflow. Running it in the debugger told me this in under one minute.
EDIT:
Your problem is in this section of cutLeaf(). First, you're assuming Leafptr->SX isn't null and you're deleting it, but it is null for the last leaf. Second, when you delete the leaf you don't set its parent's DX pointer to null. Therefore, when you traverse the list, you traverse into leaves that have been freed.
else if (Leafptr->DX == NULL)
{
tempLeafptr = Leafptr;
Leafptr = Leafptr->SX;
delete tempLeafptr;
return true;
}
The same problems exist in the else clause.