so, I am really new to programming, and I am taking a c++ class right now, in which I need to write and implement and AVL Tree, using a Doubly Linked lists to print off the contents of my tree, level by level. The teacher is really picky, so we can't use any containers from the standard libraries. My Doubly Linked list should be working fine, because I used it on a previous project, but I am getting an error when trying to combine it with the AVL Tree. I know my code probably has A LOT of things that need to be modified, but one step at a time. I am getting the following error, so I was wondering if you guys could help me figure out how to fix it. Also, if you have any suggestions on how to better my code, I would appreciate it.
In instantiation of ‘void AVLTreeSet::print(std::ofstream&) [with ItemType = std::basic_string; std::ofstream = std::basic_ofstream]’:
Lab6/main.cpp:80:20: required from here
Lab6/AVLTreeSet.h:152:49: error: cannot convert ‘LinkedList >::AVLNode*>::Node*’ to ‘AVLTreeSet >::AVLNode*’ in initialization
AVLNode* n = MyList.remove(i);
This is my AVLTree.h:
#pragma once
#include <fstream>
#include "LinkedList.h"
using namespace std;
template <typename ItemType>
class AVLTreeSet {
struct AVLNode {
ItemType item;
int height;
AVLNode* left;
AVLNode* right;
AVLNode(const ItemType& _item, AVLNode* _left = NULL, AVLNode* _right = NULL, int _height = 0) :
item(_item), left(_left), right(_right), height(_height) {}
};
AVLNode* root;
int size = 0;
public:
void RemoveBelowRoot(AVLNode *& n, const ItemType& item)
{
if (n == NULL)
{
return;
}
else if(item < n->item)
{
RemoveBelowRoot(n->left, item);
}
else if(item > n->item)
{
RemoveBelowRoot(n->right, item);
}
else if(n->left == NULL)
{
n = n->right;
}
else if (n->right == NULL)
{
n = n->left;
}
else
{
n = findMin(n->right);
RemoveBelowRoot(n->right, n->item);
}
balance(n);
size--;
// update height of nodes on this path
}
AVLNode * findMin(AVLNode* n)
{
if (n == NULL)
{
return n;
}
else if (n->left->item < n->item)
{
findMin(n->left);
}
else if(n->left->item > n->item)
{
findMin(n->right);
}
return n;
}
void remove(const ItemType& item) {
RemoveBelowRoot(root, item);
}
bool find(const ItemType& item) {
if (findBelowRoot(root, item))
{
return true;
}
return false;
}
bool findBelowRoot(AVLNode * n, const ItemType& data)
{
if (n->item == data)
{
return true;
}
else if (data > n->item)
{
findBelowRoot(n->right, data);
}
else if (data < n->item)
{
findBelowRoot(n->left, data);
}
}
void clear()
{
while (getHeight(root) != 0)
{
// remove
}
}
void addBelowRoot(AVLNode *& n, const ItemType& item)
{
if (n == NULL)
{
n = new AVLNode(item);
size++;
}
else if (item < n->item)
{
addBelowRoot(n->left, item);
}
else if(item > n->item)
{
addBelowRoot(n->right, item);
}
}
void add(const ItemType& item) {
addBelowRoot(root, item);
}
void print (ofstream& out)
{
if (root == NULL)
{
return;
}
else {
LinkedList<AVLNode *> MyList;
MyList.insert(0, root); // add root to Q
while (MyList.getSize() != 0) // While Q is not empty
//(figure out how many items are in that level)(levelsize = Q.size();)
{
for (auto i = 0; i < MyList.getSize(); i++) // for (int 1 = 0; i < LEVELSIZE; i++)
{
AVLNode* n = MyList.remove(i);
out << "level " << i << " " << n->item << "(" << n->height << ") ";
if (n->left != NULL) {
MyList.insert(MyList.getSize(), n->left);
}
if (n->right != NULL) {
MyList.insert(MyList.getSize(), n->right);
}
}
}
out << "\n ";
}
}
void balance (AVLNode *n)
{
if (getHeight(n->left) - getHeight(n->right))
{
balanceToRight(n);
}
if (getHeight(n->right) - getHeight(n->left))
{
balanceToLeft(n);
}
}
int getHeight(AVLNode *& n)
{
if (n == NULL)
{
return 0;
}
else
{
return n->height;
}
}
void balanceToRight(AVLNode * n)
{
if (getHeight(n->left->right) > getHeight(n->left->left))
{
rotateLeft(n->left);
}
rotateRight(n);
}
void rotateRight(AVLNode *&n)
{
AVLNode * k = n->left;
n->left = k->right;
k->right = n;
n = k;
// update heights of k and n
}
void rotateLeft(AVLNode *& n)
{
AVLNode * k = n->right;
n->right = k->left;
k->left = n;
n = k;
// update heights of k and n
}
void balanceToLeft(AVLNode * n)
{
if (getHeight(n->right->left) > getHeight(n->right->right)) // check with TAs if this is right
{
rotateRight(n);
}
rotateLeft(n);
}
/*void updateHeight(AVLNode *& n)
{
}*/
};
Now this is my LinkedList.h
#pragma once
#include <iostream>
#include <cstddef>
#include <fstream>
using namespace std;
template <typename ItemType>
class LinkedList {
struct Node {
ItemType item;
Node *next;
Node *prev;
Node(const ItemType &_item, Node *_next = NULL, Node *_prev = NULL) :
item(_item), next(_next), prev(_prev) { }
};
Node *head;
Node *tail;
int size = 0;
public:
~LinkedList()
{
clear();
}
void insert(int index, ItemType& item) {
if (index > size || size < 0)
{
return;
}
Node * newNode = new Node(item);
if (size == 0)
{
head = newNode;
tail = newNode;
newNode->next = NULL;
newNode->prev = NULL;
size++;
}
else if (index == 0)
{
head->prev = newNode;
newNode->next = head;
head = newNode;
size++;
}
else if (index == size) //INSERTING AT THE END
{
newNode->prev = tail;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
size++;
}
else {
Node* n = find_node(index);
newNode->next = n;
newNode->prev = n->prev;
n->prev->next = newNode;
n->prev = newNode;
size++;
}
}
Node * remove(int index) {
if (head == NULL || index >= size || index < 0)
{
return NULL;
}
else {
Node* name = find_node(index);
Node * n;
if (size == 1) // REMOVE THE ONLY NODE
{
n = head;
head = NULL;
tail = NULL;
size--;
}
else if (index == 0) //REMOVE THE FIRST NODE WHEN THERE'S MORE THAN ONE IN THE LIST
{
n = head;
head = head->next;
head->prev = NULL;
size--;
}
else if (index == size-1) //REMOVE THE LAST WHEN THERE'S MORE THAN ONE NODE IN THE LIST
{
n = tail;
tail = n->prev;
tail->next = NULL;
size--;
}
else
{
n = find_node(index);
n->prev->next = n->next;
n->next->prev = n->prev;
size--;
}
delete n;
return name;
}
}
Node * find_node(int index)
{
Node * n = NULL;
if (0 <= index && index <= size/2)
{
n = head;
for (int i = 0; i < index; i++)
{
n = n->next;
}
}
else if (size/2 < index && index <= size-1)
{
n = tail;
for (unsigned i = size-1; i > index; i--)
{
n = n->prev;
}
}
return n;
}
int getSize()
{
return size;
}
/* void print(LinkedList <string>& list, ofstream& out, int i)
{
if(head == NULL)
{
return;
}
out << "node " << i << ": " << getItem(i) << "\n";
}
Node* getItem(const int index)
{
if (index > size)
{
return NULL;
}
Node* temp = head;
for (unsigned i = 0; i < size; i++)
{
if (i == index)
{
return temp;
}
temp = temp-> next;
}
return NULL;
}*/
/* int find(const ItemType& item) {
Node * NodeP = head;
for (unsigned i = 0; i < size; i++)
{
if (NodeP->item == item)
{
return i;
}
NodeP = NodeP->next;
}
return -1;
}*/
void clear()
{
while (size != 0){
remove(0);
}
}
};
Thanks so much!
LinkedList::remove returns a LinkedList::Node pointer. You are trying to assign that into an AVLTreeSet::AVLNode pointer.
The AVLTreeSet::AVLNode * you are looking for is in the item member of the returned Node pointer.
You could do something like:
LinkedList<AVLNode *>::Node* n = MyList.remove(i);
AVLNode *treeNode = n->item;
Notes
You should be checking for NULL as the return value for remove, if it doesn't find anything.
remove actually deletes the node then returns it. You are then accessing something that has been deleted, which is Undefined Behavior. You really need to fix this before you go much further.
your for loop will only remove about half of the objects, as your are removing items from the list while still iterating further along the list using i.
Related
When I study the DataStructrue in my school, I implemented the Queue.
School's DataStructure class process is below.
student implemnted the DS
student submit in Domjudge
Domjudge score the code based by test cases.
My freind implemented the Queue like below.
#include <iostream>
#include <string>
using namespace std;
class Node {
public:
int data;
Node* next;
Node() {}
Node(int e) {
this->data = e;
this->next = NULL;
}
~Node(){}
};
class SLinkedList {
public:
Node* head;
Node* tail;
SLinkedList() {
head = NULL;
tail = NULL;
}
void addFront(int X) {
Node* v = new Node(X); // new Node
if (head == NULL) {
// list is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
int removeFront() {
if (head == NULL) {
return -1;
}else{
Node* tmp = head;
int result = head->data;
head = head->next;
delete tmp;
return result;
}
}
int front() {
if (head == NULL) {
return -1;
}else {
return head->data;
}
}
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
int empty() {
if (head == NULL) {
return 1;
}else {
return 0;
}
}
void addBack(int X) {
Node* v = new Node(X);
if (head == NULL) {
head = tail = v;
}else {
tail->next = v;
tail = v;
}
}
~SLinkedList() {}
};
class LinkedQ {
public:
int n = 0;
int capacity;
Node* f;
Node* r;
SLinkedList Q;
LinkedQ(int size) {
capacity = size;
f = NULL;
r = NULL;
}
bool isEmpty() {
return n == 0;
}
int size() {
return n;
}
int front() {
return Q.front();
}
int rear() {
return Q.rear();
}
void enqueue(int data) {
if (n == capacity) {
cout << "Full\n";
}else {
Q.addBack(data);
n++;
}
}
};
int main() {
int s, n;
string cmd;
cin >> s >> n;
listQueue q(s);
for (int i = 0; i < n; i++) {
cin >> cmd;
if (cmd == "enqueue") {
int x;
cin >> x;
q.enqueue(x);
}else if (cmd == "size") {
cout << q.size() << "\n";
}else if (cmd == "isEmpty") {
cout << q.isEmpty() << "\n";
}else if (cmd == "front") {
q.front();
}else if (cmd == "rear") {
q.rear();
}
}
}
And I implmented like this (Node class and main are same, So I pass the code)
#include <iostream>
#include <string>
using namespace std;
class Node{...};
class listQueue {
public:
Node* head;
Node* tail;
int capacity;
int n = 0;
listQueue() {
head = NULL;
tail = NULL;
}
void enqueue(int X) {
Node* v = new Node(X); // new Node
if (n==capacity) {
cout << "Full\n";
return;
}
if (head == NULL) {
// Queue is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
int front() {
if (head == NULL) {
return -1;
}else {
return head->data;
}
}
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
int empty() {
if (head == NULL) {
return 1;
}else {
return 0;
}
}
~listQueue() {}
};
test cases are just enqueue
but my friend is correct, and my code has occured memory over error.
So I check the usage of memory in Domjudge, My friend code and My code has very big gap in memory usage.
Why these two codes have memory usage gap big?
P.S I can't speak English well. If there is something you don't understand, please tell me.
First, rear is incorrect. It checks head and return tail. It happens to correct when you first set head=tail=v but it might get wrong later.
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
Check the if statement below:
v is leaked if queue is full in enqueue in your implementation.
Don't use NULL in C++. You may refer to NULL vs nullptr (Why was it replaced?).
void enqueue(int X) {
Node* v = new Node(X); // new Node
if (n==capacity) { // You're leaking v;
cout << "Full\n";
return;
}
if (head == NULL) {
// Queue is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
Made an AVL tree and everything worked well until I tested it with a larger amount of inserts. Upon deletion of a node with two children the data field within the node that is "moved" gets a strange value. Wich I've learned is some undefined behavior in c++. I don't have a clue on how to go about it. What am I missing?
AVL_Tree.cpp
#include "AVL_Tree.h"
#include "stddef.h"
#include <stdexcept>
#include <iostream>
#include <algorithm>
/*
* Constructor for TreeNode
*/
AVL_Tree::TreeNode::TreeNode(const int& data)
: data(data), height(1), leftChild(NULL), rightChild(NULL){};
void AVL_Tree::TreeNode::printNodeValue()
{
std::cout << data << "\n";
}
void AVL_Tree::TreeNode::printTree(bool isRight, const std::string& indent)
{
if(rightChild != NULL)
{
rightChild->printTree(true, indent + (isRight ? " " : " | "));
}
std::cout << indent;
if(isRight)
{
std::cout << " /";
}
else
{
std::cout << " \\";
}
std::cout << "----- ";
printNodeValue();
if(leftChild != NULL)
{
leftChild->printTree(false, indent + (isRight ? " | " : " "));
}
}
void AVL_Tree::TreeNode::printTree()
{
if(rightChild != NULL)
{
rightChild->printTree(true, "");
}
printNodeValue();
if(leftChild != NULL)
{
leftChild->printTree(false, "");
}
}
/*
* Constructor for the AVL_Tree
*/
AVL_Tree::AVL_Tree()
{
this->root = NULL;
this->size = 0;
}
/**
* Destructor
*/
AVL_Tree::~AVL_Tree()
{
destruct(this->root);
}
/**
* Deletes TreeNode objects recursively
*/
void AVL_Tree::destruct(TreeNode* root)
{
if(root != NULL)
{
destruct(root->rightChild);
destruct(root->leftChild);
delete root;
root = NULL;
}
}
/**
*Removes specified node
*/
void AVL_Tree::deleteNode(const int& data)
{
TreeNode* temp = remove(this->root, data);
if(temp != NULL)
{
this->root = temp;
size--;
}
}
/**
*Adds new node to the tree by calling insert()
*/
void AVL_Tree::add(const int& data)
{
try
{
TreeNode* node = new TreeNode(data);
this->root = insert(this->root, node);
size++;
}
catch(std::string s)
{
std::cout << s << std::endl;
}
}
void AVL_Tree::print()
{
root->printTree();
}
/**
* Prints the tree in ascending order
*/
void AVL_Tree::inOrder(TreeNode* current)
{
if(current != NULL)
{
inOrder(current->leftChild);
std::cout << current->data << std::endl;
inOrder(current->rightChild);
}
}
/**
*Recursively traverse the tree to find the correct place for the new node and then
*returns the tree.
*/
AVL_Tree::TreeNode* AVL_Tree::insert(TreeNode* current, TreeNode* newNode)
{
if(current == NULL)
{
return newNode;
}
if(newNode->data < current->data)
{
current->leftChild = insert(current->leftChild, newNode);
}
else if(newNode->data > current->data)
{
current->rightChild = insert(current->rightChild, newNode);
}
else
{
throw std::string("Data already exist in tree");
}
//return current;
return balance(current);
}
/**
* Recursively finds the TreeNode that matches 'dataToRemove' and erase it from the tree then returns the new tree
*/
AVL_Tree::TreeNode* AVL_Tree::remove(TreeNode* current, const int& dataToRemove)
{
if(current == NULL)
{
return current;
}
if(dataToRemove < current->data)
{
current->leftChild = remove(current->leftChild, dataToRemove);
}
else if(dataToRemove > current->data)
{
current->rightChild = remove(current->rightChild, dataToRemove);
}
else //if(dataToRemove == current->data)
{
TreeNode* temp = NULL;
//No children
if(current->leftChild == NULL && current->rightChild == NULL)
{
delete current;
current = NULL;
}
//One child
else if(current->leftChild != NULL && current->rightChild == NULL)
{
temp = current->leftChild;
current->data = temp->data;
current->leftChild = remove(current->leftChild, temp->data);
}
else if(current->leftChild == NULL && current->rightChild != NULL)
{
temp = current->rightChild;
current->data = temp->data;
current->rightChild = remove(current->rightChild, temp->data);
}
//Two children
else if(current->leftChild != NULL && current->rightChild != NULL)
{
temp = findSuccessor(current->rightChild);
current->data = temp->data;
remove(current->rightChild, temp->data);
}
}
return balance(current);
}
/**
* Returns height of tree
*/
int AVL_Tree::height(TreeNode* current)
{
if(current == NULL)
{
return 0;
}
return current->height;
}
/**
* Returns the balance factor for the argument(TreeNode pointer)
*/
int AVL_Tree::getBalance(TreeNode* current)
{
if(current == NULL)
{
return 0;
}
return height(current->rightChild) - height(current->leftChild);
}
/**
* Sets the height of the specified TreeNode
*/
void AVL_Tree::fixHeight(TreeNode* current)
{
int hl = height(current->leftChild);
int hr = height(current->rightChild);
current->height = (hl > hr ? hl : hr) + 1;
}
/**
* Takes TreeNode pointer as arguement and balances the tree if it isn't NULL
*/
AVL_Tree::TreeNode* AVL_Tree::balance(TreeNode* current)
{
if (current != NULL) {
fixHeight(current);
if(getBalance(current) == 2)
{
if(getBalance(current->rightChild) < 0)
{
current->rightChild = rotateRight(current->rightChild);
}
return rotateLeft(current);
}
if(getBalance(current) == -2)
{
if(getBalance(current->leftChild) > 0)
{
current->leftChild = rotateLeft(current->leftChild);
}
return rotateRight(current);
}
return current;
} else {
return NULL;
}
}
/**
* Preforms a left rotation
* Returns the rotated subtree
*/
AVL_Tree::TreeNode* AVL_Tree::rotateLeft(TreeNode* current)
{
TreeNode* right = current->rightChild;
current->rightChild = right->leftChild;
right->leftChild = current;
fixHeight(current);
fixHeight(right);
return right;
}
/**
* Preforms a right rotation
*/
AVL_Tree::TreeNode* AVL_Tree::rotateRight(TreeNode* current)
{
TreeNode* left = current->leftChild;
current->leftChild = left->rightChild;
left->rightChild = current;
fixHeight(current);
fixHeight(left);
return left;
}
/**
* Takes TreeNode pointer as argument and return the "leftest"(smallest) node in the right subtree.
*/
AVL_Tree::TreeNode* AVL_Tree::findSuccessor(TreeNode* current)
{
while(current->leftChild != NULL)
{
current = current->leftChild;
}
return current;
}
AVL_Tree.h
#ifndef AVLTREE_H
#define AVLTREE_H
#include <string>
class AVL_Tree
{
private:
struct TreeNode
{
TreeNode(const int& data);
int data;
int height;
TreeNode* leftChild;
TreeNode* rightChild;
void printTree(bool isRight, const std::string& indent);
void printTree();
void printNodeValue();
};
int size;
TreeNode* root;
TreeNode* findSuccessor(TreeNode* current);
TreeNode* remove(TreeNode* current, const int& dataToRemove);
TreeNode* insert(TreeNode* current, TreeNode* newNode);
int height(TreeNode* current);
TreeNode* balance(TreeNode* current);
int getBalance(TreeNode* current);
TreeNode* rotateLeft(TreeNode* current);
TreeNode* rotateRight(TreeNode* current);
void fixHeight(TreeNode* current);
void destruct(TreeNode* root);
TreeNode* findMin(TreeNode* current);
TreeNode* removeMin(TreeNode* current);
public:
AVL_Tree();
~AVL_Tree();
void deleteNode(const int& data);
void add(const int& data);
void print();
void inOrder(TreeNode* current);
};
#endif
main.cpp
#include "AVL_Tree.h"
#include <stdlib.h>
#include <vector>
using std::vector;
int main()
{
AVL_Tree at;
vector<int> list;
for(int i = 0; i < 20; i++)
{
int x = rand() % 100;
list.push_back(x);
at.add(x);
}
at.print();
at.add(list[0]);
at.print();
for(int i = 19; i >= 18; i--)
{
at.deleteNode(list[i]);
}
at.print();
return 0;
}
Output
output
If the data already exist in your tree, your code throws an exception. The calling code is assigning a pointer to a non returning function.
this->root = insert(this->root, node);
Test your code with some hard coded values and make sure to test with a duplicate value.
I'm writing a function that counts the leaf nodes of a height balanced tree using struct and pointers. The function takes 3 arguments: the tree, pointer to an array and the maximum depth of the tree. The length of the array is the maximum depth. When function is called the array is initialized to zero. The function recursively follows the tree structure,
keeping track of the depth, and increments the right counter whenever it reaches a leaf. The function does not follow any pointer deeper than maxdepth. The function returns 0 if there was no leaf at depth greater than maxdepth, and 1 if there was some pointer togreater depth. What is wrong with my code. Thanks.
typedef int object;
typedef int key;
typedef struct tree_struct { key key;
struct tree_struct *left;
struct tree_struct *right;
int height;
} tree_n;
int count_d (tree_n *tr, int *count, int mdepth)
{
tree_n *tmp;
int i;
if (*(count + 0) == NULL){
for (i =0; i<mdepth; i++){
*(count + i) = 0;
}
}
while (medepth != 0)
{
if (tr == NULL) return;
else if ( tree-> left == NULL || tree->right == NULL){
return (0);
}
else {
tmp = tr;
*(count + 0) = 1;
int c = 1;
while(tmp->left != NULL && tmp->right != NULL){
if(tmp-> left){
*(count + c) = 2*c;
tmp = tmp->left;
return count_d(tmp, count , mdepth);
}
else if(tmp->right){
*(count + c + 1) = 2*c + 1;
tmp = tmp->right;
return count_d(tmp,count, mdepth);
}
c++;
mpth--;
}
}
}
What is wrong with my code
One thing I noticed is that you are missing return in the recursive calls.
return count_d(tmp, count , mdepth);
// ^^^ Missing
There are two such calls. Make sure to add return to both of them.
Disclaimer: Fixing this may not fix all your problems.
Correct Function To Insert,Count All Nodes and Count Leaf Nodes
#pragma once
typedef int itemtype;
#include<iostream>
typedef int itemtype;
#include<iostream>
#include<conio.h>
#include<string>
using namespace std;
class Node
{
public:
Node* left;
Node* right;
itemtype data;
};
class BT
{
private:
int count = 0;
Node* root;
void insert(itemtype d, Node* temp);//Override Function
public:
BT();//Constructor
bool isEmpty();
Node* newNode(itemtype d);
Node* getroot();
void insert(itemtype d);//Function to call in main
int countLeafNodes(Node * temp);
int countAllNodes();//to count all nodes
}
BT::BT()//constructor
{
root = NULL;
}
bool BT::isEmpty()
{
if (root == NULL)
return true;
else
return false;
}
Node* BT::newNode(itemtype d)
{
Node* n = new Node;
n->left = NULL;
n->data = d;
n->right = NULL;
return n;
}
void BT::insert(itemtype d)//Function to call in main
{
if (isEmpty())
{
Node* temp = newNode(d);
root = temp;
}
else
{
Node* temp = root;
insert(d, temp);
}
count++;//to count number of inserted nodes
}
void BT::insert(itemtype d, Node* temp)//Private Function which is overrided
{
if (d <= temp->data)
{
if (temp->left == NULL)
{
Node* n = newNode(d);
temp->left = n;
}
else
{
temp = temp->left;
insert(d, temp);
}
}
else
{
if (temp->right == NULL)
{
temp->right = newNode(d);
}
else
{
temp = temp->right;
insert(d, temp);
}
}
}
int BT::countAllNodes()
{ return count; }
int BT::countLeafNodes(Node* temp)
{
int leaf = 0;
if (temp == NULL)
return leaf;
if (temp->left == NULL && temp->right == NULL)
return ++leaf;
else
{
leaf = countLeafNodes(temp->left) + countLeafNodes(temp->right);
return leaf;
}
}
void main()
{
BT t;
t.insert(7);
t.insert(2);
t.insert(3);
t.insert(15);
t.insert(11);
t.insert(17);
t.insert(18);
cout<<"Total Number Of Nodes:" <<t.countAllNodes() <<endl;
cout << "Leaf Nodes:" << t.countLeafNodes(t.getroot()) << endl;
_getch();
}
Output:
Ouput
I'm having a segmentation fault on the following piece of code:
main.cpp
List list;
Movie *m = new Movie();
list+m; //For testing the operator +
EDIT: Full List.cpp with all functions
#include "List.h"
using namespace std;
List::List() : head(0),tail(0),size(0) { }
List::~List()
{
Node *current = head;
while( current != 0 ) {
Node* next = current->getNext();
delete current;
current = next;
}
head = 0;
}
void List::addMovie(Movie *movie)
{
Node *curNode = new Node(movie);
if(head == NULL)
{
head = curNode;
tail = curNode;
curNode->setNext(NULL);
curNode->setPrevious(NULL);
}
else
{
curNode->setNext(NULL);
tail->setNext(curNode);
curNode->setPrevious(tail);
tail = curNode;
}
size++;
}
Node *List::first()
{
return head;
}
Node *List::last()
{
return tail;
}
void List::addMovie(List & list)
{
Node *curNode = list.first();
while(curNode)
{
addMovie(curNode->getContent());
curNode = curNode->getNext();
}
}
void List::removeMovie(Movie *movie)
{
if(size == 0) return;
bool found = false;
Node *curNode = head;
while(curNode)
{
if(curNode->getContent()->getTitle().compare(movie->getTitle()) == 0)
{
found = true;
break;
}
curNode = curNode->getNext();
}
if(!found) return;
if(curNode == head && curNode == tail)
{
head = NULL;
tail = NULL;
delete curNode;
return;
}
if(curNode == head && curNode != tail)
{
head = curNode->getNext();
curNode->getNext()->setPrevious(NULL);
delete curNode;
return;
}
if(curNode != head && curNode == tail)
{
tail = curNode->getPrevious();
curNode->getPrevious()->setNext(NULL);
delete curNode;
return;
}
if(curNode != head && curNode != tail)
{
curNode->getPrevious()->setNext(curNode->getNext());
curNode->getNext()->setPrevious(curNode->getPrevious());
delete curNode;
return;
}
size--;
}
void List::removeMovie(List &list)
{
Node *curNode = list.first();
while(curNode)
{
removeMovie(curNode->getContent());
curNode = curNode->getNext();
}
}
int List::getSize()
{
return size;
}
Movie *List::findMovie(string title)
{
Node *curNode = head;
while(curNode)
{
if(title.compare(curNode->getContent()->getTitle()) == 0) return curNode->getContent();
curNode = curNode->getNext();
}
return NULL;
}
void List::clean()
{
head = tail = NULL;
size = 0;
}
void List::operator =(const List& list)
{
head = list.head;
tail = list.tail;
size = list.size;
}
void List::operator +=(Movie *movie)
{
addMovie(movie);
}
void List::operator +=(const List& list)
{
Node *curNode = list.head;
while(curNode)
{
addMovie(curNode->getContent());
curNode = curNode->getNext();
}
}
List List::operator +(Movie *m)
{
cout << "ok" << endl;
List list = *this;
cout << "ok" << endl;
//list += m;
//Node *f = list.first();
/*while(f)
{
cout << f->getContent()->getTitle() << endl;
f = f->getNext();
}*/
//return list;
//Crashing after this
}
List List::operator +(const List& list)
{
List tmp = *this;
tmp.size++;
return tmp;
}
I get a seg fault after doing list+m, getting this while debugging:
No source available for "libstdc++-6!_ZNKSs7_M_dataEv() at 0x6fc5e26c"
I am writing a program that is sort of like boggle, but I am having a problem making Pairs and putting them in lists and then taking them out of lists.
List.cc
#include <iostream>
#include <cassert>
#include <cstdlib>
#include "list.h"
using namespace std;
List::Node::Node()
{
prev = next = NULL;
}
List:: List()
{
front = new Node()
rear = new Node()
front->next = rear;
rear->prev = front;
currentIndex=0;
current = front->next;
size=0;
}
List::~List()
{
_setCurrentIndex(0);
while(current)
{
Node *temp = current;
current = current -> next;
delete temp;
}
//not showing deep copy function b/c it isn't important for this program
void List::add(const ElementType & item, size_t index)
{
assert(0<=index && index <= size);
_setCurrentIndex(index);
size++;
Node *born = new Node;
born->data = item;
born->prev = current->prev;
born->prev->next = current;
born->prev = born;
current = born;
}
void List::removeAt(size_t index)
{
assert(0<=index<=getSize());
_setCurrentIndex(index);
Node *old = current;
current->prev->next = current->next;
current->next->prev = current->prev;
delete old;
size--;
}
void List::remove(const ElementType & item)
{
for(size_t i=0; i<size; i++)
{
_setCurrentIndex(i);
if(find(item)<getSize())
{
Node *tempOld = current;
current->next->prev = current->prev;
current->prev->next = current->next;
current = current->next;
delete tempOld;
size--;
}
}
}
size_t List::find(const ElementType & item) const
{
for(size_t i=0; i<size; i++)
{
_setCurrentIndex(i)
if(get(i) == item)
return i;
}
return getSize();
}
List::ElementType List::get(size_t index) const
{
assert(0 <= index < size);
_setCurrentIndex(index);
assert(current->next != NULL);
return current->data;
}
size_t List::getSize() const
{
return size;
}
void List::output(std::ostream & ostr) const
{
for(size_t i=0; i<size; i++)
{
_setCurrentIndex(i);
ostr << current->data << " ";
}
ostr << endl;
}
void List:: _setCurrentIndex(size_t index) const
{
int x;
if(currentIndex > index)
x = currentIndex - index;
else
x = index-currentIndex;
if(index < (sizez_t)x)
{
current = front->next;
curentIndex=0;
while(currentIndex != index)
{
current = current->next;
currentIndex++;
}
}
else if((size-index) < (size_t)x)
{
current = rear;
currentIndex = size;
while(currentIndex != index)
{
current = current->prev;
currentIndex--;
}
}
else
{
if(currentIndex > index)
{
while(currentIndex!=index)
{
current = current->prev;
currentIndex--;
}
}
else
{
while(currentIndex!=index)
{
current = current->next;
currentIndex++;
}
}
}
}
It seems that when I try to add, or remove anything from my List it results in problems with my asserition and it aborts or it simply seg faults.
If i put a statement as simple as
List history;
Pair p1 = Pair(1,1)
history.add(p1,0)
results in:
scramble: list.cc:154: Pair List::get(size_t) const: assertion 0 <= index <size failed
aborted
The assertion:
assert(0 <= index < size);
in incorrect. Change to:
assert(0 <= index && index < size);