I have written a linked list based queue, where each node is linked to the node behind it in the queue. Every other function in the program works with no problems. For some reason this destructor is giving me some issues, and I am not sure why.
I am getting this error:
Exception thrown: read access violation.
temp was 0xCDCDCDCD.
Thanks for any help given.
#pragma once
#include <iostream>
#include "Node.h"
template <typename T>
class LQueue
{
Node<T>* front;
Node<T>* end;
int length;
public:
LQueue();
~LQueue();
//Add item into queue
void enqueue(T x);
//Remove item from front of queue
void dequeue();
//return item at front of queue
T peek();
//Is queue empty?
bool isEmpty();
int getLength() { return length; }
};
template<typename T>
inline LQueue<T>::LQueue()
{
front = nullptr;
end = nullptr;
length = 0;
}
template<typename T>
inline void LQueue<T>::enqueue(T x)
{
Node<T>* temp = new Node<T>;
temp->data = x;
length++;
if (isEmpty())
{
temp->next = nullptr;
front = temp;
end = temp;
}
else
{
end->next = temp;
end = temp;
}
}
template<typename T>
inline void LQueue<T>::dequeue()
{
if (isEmpty())
{
std::cout << "\n[!] Empty Queue, Nothing To Remove.\n";
return;
}
if (end == front)
{
delete front;
front = nullptr;
end = nullptr;
}
else
{
Node<T>* temp = front->next;
delete front;
front = temp;
}
length--;
}
template<typename T>
inline T LQueue<T>::peek()
{
return front->data;
}
template<typename T>
inline bool LQueue<T>::isEmpty()
{
if (front == nullptr)
return true;
else
return false;
}
template<typename T>
inline LQueue<T>::~LQueue()
{
Node<T>* temp = front;
while (temp != nullptr)
{
Node<T>* temp2 = temp;
temp = temp->next;
delete temp2;
}
}
Error from visual studios
Thanks to #Yksisarvinen, I have fixed my problem.
The end->next was only initialized if the queue was empty. I didn't initialize end->next if queue wasn't empty.
Old Code
template<typename T>
inline void LQueue<T>::enqueue(T x)
{
Node<T>* temp = new Node<T>;
temp->data = x;
length++;
if (isEmpty())
{
temp->next = nullptr;
front = temp;
end = temp;
}
else
{
end->next = temp;
end = temp;
}
}
New Code:
template<typename T>
inline void LQueue<T>::enqueue(T x)
{
Node<T>* temp = new Node<T>;
temp->data = x;
length++;
temp->next = nullptr;
if (isEmpty())
{
front = temp;
end = temp;
}
else
{
end->next = temp;
end = temp;
}
}
Related
I am trying to implement the peek() function of a Stack class and have this issue where I cannot return the top object of the stack, but instead get an error. I have tried removing the & to the peek function and tried to set it to a const, but I still get errors. Would the issue be outside of this function? as I am not sure what else I can try to solve this problem.
Error:
LStack.h:55:28: error: cannot bind non-const lvalue reference of type ‘int&’
to
an rvalue of type ‘int’
return data.get_current();
LStack.h
#include "LinkedList.h"
#include <cstdlib>
#include <iostream>
template <typename T>
class LStack
{
public:
//mutator member functions
LStack(){}
~LStack(){}
void push(const T& obj) //insert obj at the top of the stack
{
data.add_to_head(obj);
numofstacks++;
}
T pop() //remove and return the top object from the stack, error if stack is empty
{
if (is_empty()){
std::cout << "Stack is empty";
}
else{
data.remove_from_head();
numofstacks--;
return data.get_current();
}
}
bool is_empty() const //return a boolean indicating whether the stack is empty
{
return (size() == 0);
}
//query member functions
int size() const //return the number of objects in the stack
{
return numofstacks;
}
//return a reference to the object at the top of the stack, NULL if the stack is empty, (also refered to as top())
T& peek()
{
if (is_empty()){
std::cout << "Stack is empty";
}
else{
//return top of the stack object
return data.get_current();
}
}
private:
LinkedList<T> data;
int used;
int numofstacks;
};
LinkedList.h
#include "Node.h"
#include <cstdlib>
#include <iostream>
template <typename T>
class LinkedList
{
public:
LinkedList() //constructor
{
head = NULL;
tail = NULL;
list_length=0;
}
~LinkedList()//destructor since we're creating the linked list on the heap
{
while (head != NULL)
{
remove_from_head();
}
tail = NULL;//not sure if in or out of while loop
}
LinkedList(T& item)
{
head = new Node<T>();
head->set_data(item);
tail = head;
list_length = 1;
}
void add_to_head(T item)
{
if (list_length == 0){ //if list is empty
head = new Node<T>();
head->set_data(item);
tail = head;
list_length = 1;
}
else //Else if list is not empty.. Insert node at the head
{
Node<T>* head_insert = new Node<T>();
head_insert->set_data(item);
head->set_prev(head_insert);
head_insert->set_next(head);
head = head_insert;
list_length++;
head_insert = NULL;
}
}
void add_to_tail(T item)
{
if (list_length == 0){
head = new Node<T>();
head->set_data(item);
tail = head;
list_length = 1;
}
else //insert node at tail
{
Node<T>* tail_insert = new Node<T>();
tail_insert->set_data(item);
tail->set_next(tail_insert);
tail_insert->set_prev(tail);
tail = tail_insert;
list_length++;
tail_insert = NULL;
}
}
void remove_from_head()
{
if (list_length == 0){
return;
}
else if (list_length == 1){
delete head;
head = NULL;
tail = NULL;
list_length--;
return;
}
else
{
Node<T>* temp_head = head;
head = temp_head->get_next();
delete temp_head;
list_length--;
temp_head = NULL;
}
}
void remove_from_tail()
{
if (list_length == 0){
return;
}
else if (list_length == 1)
{
delete head;
head = NULL;
tail = NULL;
list_length--;
return;
}
else
{
Node<T>* temp_tail = tail;
tail = temp_tail->get_prev();
delete temp_tail;
list_length--;
temp_tail = NULL;
}
}
std::size_t size()
{
return list_length;
}
T get_current() // RESULTS IN SEG ERROR
{
return current->get_data();
}
void forward()
{
current = current->get_next();
}
void back()
{
current = current->get_prev();
}
void move_to_head()
{
current = head;
}
void move_to_tail()
{
current = tail;
}
private: //private members
Node<T>* head; //point to start of list
Node<T>* tail; //point to end of list
Node<T>* current; //optional - used to refer to a node in our list
std::size_t list_length;
};
Would the issue be outside of this function? as I am not sure what else I can try to solve this problem.
I am having some trouble with this function I wrote to delete at some position in a double linked list. I feel like I am leaking memory and I am not doing this property for a double linked list.
Here is the code:
template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
Node* prev = new Node;
Node* current = head;
for(int i = 1; i < pos; i++) {
prev = current;
current = current->next;
}
prev->next = current->next;
}
This is pretty much what I did for a single linked list so I know this is not right. If anyone has any suggestions on how to do this for a double linked list I would really appreciate it.
EDIT:
I think this works correctly now:
template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
Node* temp = nullptr;
Node* current = head;
for(int i = 1; i < pos; i++) {
temp = current;
current = current->next;
}
temp->previous = current->previous;
temp->next = current->next;
}
Here is the entire code:
#ifndef DoubleLinkedLists_h
#define DoubleLinkedLists_h
template <class T>
class DoubleLinkedLists {
private:
struct Node {
T data;
Node* next;
Node* previous;
};
Node* head;
Node* tail;
public:
// Constructors
DoubleLinkedLists() : head(nullptr), tail(nullptr) {} // empty constructor
DoubleLinkedLists(DoubleLinkedLists const& value); // copy constructor
DoubleLinkedLists<T>(DoubleLinkedLists<T>&& move) noexcept; // move constuctor
DoubleLinkedLists<T>& operator=(DoubleLinkedLists&& move) noexcept; // move assignment operator
~DoubleLinkedLists(); // destructor
// Overload operators
DoubleLinkedLists& operator=(DoubleLinkedLists const& rhs);
friend std::ostream& operator<<(std::ostream& str, DoubleLinkedLists<T> const& data) {
data.display(str);
return str;
}
// Member functions
void swap(DoubleLinkedLists& other) noexcept;
void push(const T& theData);
void push(T&& theData);
void display(std::ostream& str) const;
void insertHead(const T& theData);
void insertTail(const T& theData);
void insertPosition(int pos, const T& theData);
void deleteHead();
void deleteTail();
void deletePosition(int pos);
bool search(const T& x);
};
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists const& value) : head(nullptr), tail(nullptr) {
for(Node* loop = value->head; loop != nullptr; loop = loop->next) {
push(loop->data);
}
}
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists<T>&& move) noexcept : head(nullptr), tail(nullptr) {
move.swap(*this);
}
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists<T> &&move) noexcept {
move.swap(*this);
return *this;
}
template <class T>
DoubleLinkedLists<T>::~DoubleLinkedLists() {
while(head != nullptr) {
deleteHead();
}
}
template <class T>
void DoubleLinkedLists<T>::swap(DoubleLinkedLists<T> &other) noexcept {
using std::swap;
swap(head,other.head);
swap(tail,other.tail);
}
template <class T>
void DoubleLinkedLists<T>::push(const T& theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = tail;
if(head == nullptr) {
head = newNode;
}
else {
tail->next = newNode;
}
tail = newNode;
}
template <class T>
void DoubleLinkedLists<T>::push(T&& theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = tail;
if(head == nullptr) {
head = newNode;
}
else {
tail->next = newNode;
}
tail = newNode;
}
template <class T>
void DoubleLinkedLists<T>::display(std::ostream &str) const {
for(Node* loop = head; loop != nullptr; loop = loop->next) {
str << loop->data << "\t";
}
str << "\n";
}
template <class T>
void DoubleLinkedLists<T>::insertHead(const T &theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->next = head;
head->previous = newNode;
head = newNode;
}
template <class T>
void DoubleLinkedLists<T>::insertTail(const T &theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = tail;
tail->next = newNode;
tail = newNode;
}
template <class T>
void DoubleLinkedLists<T>::insertPosition(int pos, const T &theData) {
if (pos < 0) {
throw std::invalid_argument("pos is not a valid index");
}
Node* current = head;
Node* previous = nullptr;
while(pos-- > 0) {
if(!current) {
throw std::invalid_argument("pos is not a valid index");
}
previous = current;
current = current->next;
}
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = previous;
newNode->next = current;
if(newNode->previous) {
newNode->previous->next = newNode;
}
else {
head = newNode;
}
if(newNode->next) {
newNode->next->previous = newNode;
}
else {
tail = newNode;
}
}
template <class T>
void DoubleLinkedLists<T>::deleteHead() {
if (head != nullptr) {
Node* old = head;
head = head->next;
delete old;
}
else {
throw std::invalid_argument("the list is empty!");
}
}
template <class T>
void DoubleLinkedLists<T>::deleteTail() {
if(head != nullptr) {
Node* prev = nullptr;
Node* current = head;
while(current->next != nullptr) {
prev = current;
current = current->next;
}
tail = prev;
prev->next = nullptr;
delete current;
}
else {
throw std::invalid_argument("The list is already empty, nothing to delete.");
}
}
template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
Node* temp = nullptr;
Node* current = head;
for(int i = 1; i < pos; i++) {
temp = current;
current = current->next;
}
temp->previous = current->previous;
temp->next = current->next;
}
template <class T>
bool DoubleLinkedLists<T>::search(const T &x) {
Node* current = head;
while(current != nullptr) {
if(current->data == x) {
return true;
}
current = current->next;
}
return false;
}
#endif /* DoubleLinkedLists_h */
And here is the main.cpp file that tests it:
#include <iostream>
#include "DoubleLinkedLists.h"
int main(int argc, const char * argv[]) {
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Double Linked List //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
DoubleLinkedLists<int> obj;
obj.push(2);
obj.push(4);
obj.push(6);
obj.push(8);
obj.push(10);
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"---------------Displaying All nodes---------------";
std::cout<<"\n--------------------------------------------------\n";
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Inserting At Start----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertHead(50);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"-----------------Inserting At End-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertTail(20);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"-------------Inserting At Particular--------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertPosition(5,60);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Deleting At Start-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deleteHead();
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Deleting At End-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deleteTail();
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"--------------Deleting At Particular--------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deletePosition(5);
std::cout << obj << std::endl;
std::cout << std::endl;
obj.search(8) ? printf("Yes"):printf("No");
return 0;
}
So you would need to do something like this. Note that your code does not handle the case of an index out of range (i.e. the position specified is either negative or is longer the list). It looked like you don't maintain a count of your list length (in the linked code) so I added a check for current != nullptr into the for loop as well as after the for loop to handle the case of the pos being longer than the list. In that case, now the code will do nothing, but you could throw an out of range exception or something like that to indicate the invalid condition. In the case of removing the head you also need to take care to fix up the head pointer. I am assuming you might have a tail pointer as well, so you need to add checks to see if you are removing the tail and fix that up as well.
Note
I didn't compile this and so there may be a typo or two, but it should at least point you in the right direction.
void DoubleLinkedLists<T>::deletePosition(int pos) {
if (pos < 0) {} // Should do something in this case
Node* current = head;
// Added null check to keep from continuing past the end of the list
for(int i = 1; i < pos && current != nullptr; i++) {
current = current->next;
}
if (current != nullptr)
{
// If we are at the head, there isn't a previous
if (current != head)
{
current->previous->next = current->next;
}
else
{
// In this case, we are removing the head, need to reset head to the next Node
head = current->next;
}
if (current->next != nullptr)
{
current->next->previous = current->previous;
}
else if (current == tail)
{
// In this case we are removing the tail, need to reset tail pointer
tail = current->previous;
}
delete current; // Cleans up the node we are deleting
}
}
As the title suggests, I am trying to learn data structures and I am starting with a linked list. I decided to make it generic since I thought it would be useful to do to handle other data types.
I am getting these associated errors:
I am not sure what I am doing wrong and I cannot identify the error. Here is my code starting with the header file:
#ifndef LinkedList_hpp
#define LinkedList_hpp
template<class T>
struct Node {
T data;
Node<T>* next;
};
template<class T>
class SingleLinkedList {
private:
Node<T>* head, tail;
public:
SingleLinkedList();
void createNode(const T& theData);
void display();
void insert_start(const T& theData);
void insert_position(int pos, const T& theData);
void delete_first();
void delete_last();
void delete_position(int pos);
Node<T>* search(Node<T>* head, const T& target);
};
#endif /* LinkedList_hpp */
Now here is the associated .cpp file:
#include "LinkedList.hpp"
#include <iostream>
template<class T>
SingleLinkedList<T>::SingleLinkedList() {
head = nullptr;
tail = nullptr;
}
template<class T>
void SingleLinkedList<T>::createNode(const T& theData) {
Node<T>* temp = new Node<T>;
temp->data = theData;
temp->next = nullptr;
if(head == nullptr) {
head = temp;
tail = temp;
temp = nullptr;
}
else {
tail->next = temp;
tail = temp;
}
}
template<class T>
void SingleLinkedList<T>::display() {
Node<T>* temp = new Node<T>;
temp = head;
while(temp != nullptr) {
std::cout << temp->data << "\t";
temp = temp->next;
}
}
template<class T>
void SingleLinkedList<T>::insert_start(const T& theData) {
Node<T>* temp = new Node<T>;
temp->data = theData;
temp->next = head;
head = temp;
}
template<class T>
void SingleLinkedList<T>::insert_position(int pos, const T &theData) {
Node<T>* previous = new Node<T>;
Node<T>* current = new Node<T>;
Node<T>* temp = new Node<T>;
temp = head;
for(int i = 1; i < pos; i++) {
previous = current;
current = current->next;
}
temp->data = theData;
previous->next = temp;
temp->next = current;
}
template<class T>
void SingleLinkedList<T>::delete_first() {
Node<T>* temp = new Node<T>;
temp = head;
head = head->next;
delete temp;
}
template<class T>
void SingleLinkedList<T>::delete_last() {
Node<T>* previous = new Node<T>;
Node<T>* current = new Node<T>;
current = head;
while(current->next != nullptr) {
previous = current;
current = current->next;
}
tail = previous;
previous->next = nullptr;
delete current;
}
template<class T>
void SingleLinkedList<T>::delete_position(int pos) {
Node<T>* previous = new Node<T>;
Node<T>* current = new Node<T>;
current = head;
for(int i = 1; i < pos; i++) {
previous = current;
current = current->next;
}
previous->next = current->next;
}
And finally here is the main.cpp file where I attempt to test the code:
#include <iostream>
#include "LinkedList.hpp"
int main(int argc, const char * argv[]) {
SingleLinkedList<int> obj;
obj.createNode(2);
obj.createNode(4);
obj.createNode(6);
obj.createNode(8);
obj.display();
return 0;
}
You need to put the implementation of your member functions into the header file.
so I have an assignment where I need to create a doubly linked list and then create a stack and queue class and inherit from the linkedlist class in order to create an RPN calculator. So far I have created my doubly linkedlist class and the other to classes. However, I am having trouble understanding how I will inherit and use the linked list class with the stack and queue. I will provide what I have so far.
I have gone to tutoring and have not had much help so I thought I would look for some extra help, do not want homework done for me but to just be pointed in the right direction.
Stack.h
using std::iterator;
using std::vector;
using std::string;
template<class T>
class Stack : public vector<T>
{
private:
T getElement(bool erase);
typename std::vector<T> ::iterator pEnd;
T top;
public:
Stack();
T pop();
T peek();
void push(T elem);
};
template<class T>
Stack<T>::Stack()
{
}
template<class T>
void Stack<T>::push(T elem)
{
this->push_back(elem);
}
template<class T>
T Stack<T>::peek()
{
return this->getElement(false);
}
template<class T>
T Stack<T>::pop()
{
return this->getElement(true);
}
template<class T>
T Stack<T>::getElement(bool erase)
{
this->pEnd = this->end() - 1;
T tmp;
if (this->size() > 0)
{
tmp = *this->pEnd;
if (erase) {
this->erase(pEnd);
}
}
return tmp;
}
Queue.h
using namespace std;
class Queue
{
private:
int items[MAXQUEUE];
int head;
int tail;
public:
Queue();
bool isEmpty();
bool isFull();
bool enqueue(int item);
int dequeue();
int peek();
};
Queue::Queue()
:head(QEMPTY), tail(QEMPTY)
{
}
bool Queue::isEmpty()
{
return this->head == this->tail;
}
bool Queue::isFull()
{
return this->tail == MAXQUEUE;
}
bool Queue::enqueue(int item)
{
if (this->isFull())
return false;
this->items[this->tail] = item;
tail = (tail + 1) % MAXQUEUE;
return true;
}
int Queue::dequeue()
{
if (this->isEmpty())
return EMPTY;
int item = this->items[head];
this->head = (this->head + 1) % MAXQUEUE;
return item;
}
int Queue::peek() {
return this->tail;
}
doublylinkedlist.h
using std::iterator;
using std::vector;
using std::string;
/*START OF NODE CLASS*/
/*---------------------------------------------*/
template<class T>
struct Node
{
T Data;
T Search;
T value;
Node<T>*Next;
Node<T>*Prev;
};
template<class T>
class LinkedList
{
private:
Node<T> *Head;
public:
LinkedList();
void addNode(T Data);
void deleteNode(T Search);
void insert(T Search, T value);
void printListBackwards();
void printListForwards();
};
template<class T>
LinkedList<T>::LinkedList()
{
this->Head = NULL;
}
template<class T>
void LinkedList<T>::addNode(T data)
{
if (Head == NULL)
{
Head = new Node<T>;
Head->Data = data;
Head->Next = NULL;
Head->Prev = NULL;
}
else
{
Node<T>*p = this->Head;
while (p->Next != NULL)
p = p->Next;
Node<T>*n = new Node<T>;
n->Data = data;
n->Next = NULL;
p->Next = n;
n->Prev = p;
}
}
template<class T>
void LinkedList<T>::insert(T Search, T value)
{
Node *p = Head;
while (p->Data != Search)
{
p = p->Next;
}
Node *n = new Node;
n->Data = value;
n->Next = p->Next;
p->Next = n;
}
template<class T>
void LinkedList<T>::deleteNode(T Search)
{
Node *p = Head;
while (p->Next->Data != Search)
{
p = p->Next;
}
Node *delPtr = p->Next;
p->Next = p->Next->Next;
delete delPtr;
}
template<class T>
void LinkedList<T>::printListBackwards()
{
Node<T> *p = Head;
while (p->Next != NULL)
{
p = p->Next;
}
while (p != NULL)
{
cout << p->Data<< endl;
p = p->Prev;
}
}
template<class T>
void LinkedList<T>::printListForwards()
{
Node<T> *p = Head;
while (p != NULL)
{
cout << p->Data << endl;
p = p->Next;
}
}
A doubly linked list can be added to at the head or the tail, and removed at the tail.
A stack pushes at one end (the head?) and pops at the same end (the head).
A queue pushes at one end (the tail) and pops at the other end (the head).
I've gone through a bunch of threads trying to understand what is going on exactly with linked lists and bubblesort, and I think I get the bulk of it.
Right now my program is simply crashing when I get to the sort function and I am not sure why. Hopefully another set of eyes will see what I do not.
Any help is greatly appreciated.
DoublyList.h:
#include "listNode.h"
#ifndef DOUBLYLIST_H
#define DOUBLYLIST_H
template <typename T>
class DoublyList
{
public:
DoublyList();
~DoublyList();
void addFront(T d);
void addBack(T d);
T removeFront();
T removeBack();
T peak();
bool isEmpty();
int getSize();
void printList();
void sortList();
private:
ListNode<T> *front;
ListNode<T> *back;
int numOfElements;
};
template <typename T>
DoublyList<T>::DoublyList(){
front = NULL;
back = NULL;
numOfElements = 0;
}
template <typename T>
DoublyList<T>::~DoublyList(){
if(numOfElements!=0){
ListNode<T> *current;
current = front;
while (current != back)
{
ListNode<T> *temp = current;
current = current->next;
temp->next = NULL;
temp->prev = NULL;
delete temp;
numOfElements--;
}
//at this point current = back, now delete it
current->next = NULL;
current->prev = NULL;
delete current;
numOfElements--;
}
//this is a safeguard if you create a LL and then delete it without doing anything to it
else{
cout<<"deleted empty LL"<<endl;
delete front;
delete back;
}
}
template <typename T>
void DoublyList<T>::addFront(T d)
{
ListNode<T> *node = new ListNode<T>();
node->data = d;
if (isEmpty()){
back = node;
}
else{
front->prev = node;
}
node->next = front;
front = node;
++numOfElements;
}
template <typename T>
T DoublyList<T>::removeFront()
{
if (isEmpty()){
return T();
}
else
{
ListNode<T>* temp = front;
if (front->next == 0){
back = 0;
}
else
{
front->next->prev = 0;
}
front = front->next;
temp->next = 0;
T theData = temp->data;
delete temp;
--numOfElements;
return theData;
}
}
template <typename T>
void DoublyList<T>::addBack(T d)
{
ListNode<T> *node = new ListNode<T>();
node->data = d;
if (isEmpty()){
front = node;
}
else{
back->next = node;
}
node->prev = back;
back = node;
++numOfElements;
}
template <typename T>
T DoublyList<T>::removeBack()
{
if (isEmpty()) {
return T();
}
else
{
ListNode<T>* temp;
temp = back;
if (back->prev == 0){
front = 0;
}
else{
back->prev->next = 0;
}
back = back->prev;
temp->prev = 0;
T theData = temp->data;
delete temp;
--numOfElements;
return theData;
}
}
template <typename T>
T DoublyList<T>::peak()
{
if (isEmpty()) {
return T();
}
return front->data;
}
template <typename T>
int DoublyList<T>::getSize(){
return numOfElements;
}
template <typename T>
bool DoublyList<T>::isEmpty(){
if(numOfElements == 0){
return true;
}
else{
return false;
}
}
template <typename T>
void DoublyList<T>::printList(){
if(numOfElements!=0){
ListNode<T> *current = front;
while(current!=back)
{
cout<<current->data<<endl;
current = current->next;
}
cout<<back->data<<endl;
}
else{
cout<<"list is empty"<<endl;
}
}
template <typename T>
void DoublyList<T>::sortList(){
int size = getSize();
ListNode<T> *current;
ListNode<T> *dummy;
ListNode<T> *next;
if(current == NULL) return;
if(current -> next == NULL) return;
int swapped = 1;
while(swapped){
swapped = 0; //last pass unless there is a swap
while(current -> next != NULL){
if(current-> data < current -> next -> data){
swapped = 1; //swap, will need to re-enter while loop
//actual number swap
dummy -> data = current -> data;
current -> data = current -> next -> data;
current -> next -> data = dummy -> data;
}
current = current -> next;
}
}
}
#endif
listNode.h:
#include <iostream>
#ifndef LISTNODE_H
#define LISTNODE_H
using namespace std;
template <typename T>
class ListNode
{
public:
T data;//the data that we will store
ListNode();
ListNode(int d);
~ListNode();
ListNode *next;//int and ptr and the member variables
ListNode *prev;
};
template <typename T>
ListNode<T>::ListNode(int d){
data = d;
next = NULL;
prev = NULL;
}
template <typename T>
ListNode<T>::ListNode(){}
template <typename T>
ListNode<T>::~ListNode(){
delete next;
delete prev;
cout<<"deleted Node"<<endl;
}
#endif
testList.cpp
#include <iostream>
#include "doublyList.h"
#include "genericQueue.h"
int main(){
DoublyList<int> testQueue;
testQueue.addBack(3);
testQueue.addBack(5);
testQueue.addBack(2);
testQueue.addBack(10);
testQueue.addBack(1);
cout << "Before Sort: " << endl;
testQueue.printList();
cout << "After Sort: " << endl;
testQueue.sortList();
testQueue.printList();
}
The erors I could find so far are:
Your default ListNode() constructor doesn't null the next and prev pointers.
In void DoublyList<T>::sortList() you don't initialize dummy, so it just points into nowhere. Actually there is no reason to use a node list at all, you can just directly use a variable of type T.
You don't initialize current in the same function and you actually should reset current to e.g. front at the beginning of each outer loop.
You don't use next at all (and don't need to), so just remove it.
To sum it up, this is what void DoublyList<T>::sortList() could look like:
template <typename T>
void DoublyList<T>::sortList(){
int size = getSize();
ListNode<T> *current=front;
T dummy;
if (current == NULL) return;
if (current->next == NULL) return;
int swapped = 1;
while (swapped){
current = front;
swapped = 0; //last pass unless there is a swap
while (current->next != NULL){
if (current->data < current->next->data){
swapped = 1; //swap, will need to re-enter while loop
//actual number swap
dummy = current->data;
current->data = current->next->data;
current->next->data = dummy;
}
current = current->next;
}
}
}
and this is my suggestion for the ListNode constructor.
template <typename T>
ListNode<T>::ListNode() :
next(nullptr),
prev(nullptr),
data{}
{}
Besides that, I also agree with DaveB that swapping pointers is the approach you should actually use.
To start with you need to initialize current in your sort function,
current = first;
template <typename T>
void DoublyList<T>::sortList(){
ListNode<T> *current;
ListNode<T> *next;
T tmp;
current = front;
if(current == NULL) return;
if(current -> next == NULL) return;
int swapped = 1;
while(swapped){
swapped = 0; //last pass unless there is a swap
while(current->next != nullptr){
if(current->data < current->next->data){
swapped = 1; //swap, will need to re-enter while loop
//actual number swap
tmp = current->data;
current->data = current->next->data;
current->next->data = tmp;
}
current = current -> next;
}
if (swapped) // go back to start of list for next pass
current = front;
}
}