Count Leaf Nodes In a Generic Tree (Recursively) - c++

I am trying to make a C++ program to count the number of Leaf Nodes in a generic tree using a Recurisve approach.
here is my code:
int countLeafNodes(TreeNode<int> *root)
{
if (root = NULL)
{
return 0;
}
int total = 0;
if (root->children.size() == 0)
{
return 1;
}
for (int i = 0; i < root->children.size(); i++)
{
total += countLeafNodes(root->children[i]);
}
return total;
}
int main()
{
TreeNode<int> *root = takeInputLevelWise();
cout << "Total Leaf Nodes = " << countLeafNodes(root) << endl;
return 0;
}
But I don't get any output on my editor (vs code) so I tested it on an online judge and it was giving SIGSEGV error. I know we get that error for an Invalid memory reference but I don't understand where in my code I am doing that mistake. Please someone tell me what's wrong with the code and why it is not working.
here is the complete code:
#include <bits/stdc++.h>
using namespace std;
template <typename T>
class TreeNode
{
public:
T data;
vector<TreeNode<T> *> children;
TreeNode(T data)
{
this->data = data;
}
~TreeNode()
{
for (int i = 0; i < children.size(); i++)
{
delete children[i];
}
}
};
TreeNode<int> *takeInputLevelWise()
{
int rootData;
cout << "Enter Root Data" << endl;
cin >> rootData;
TreeNode<int> *root = new TreeNode<int>(rootData);
queue<TreeNode<int> *> pendingNode;
pendingNode.push(root);
while (!pendingNode.empty())
{
TreeNode<int> *front = pendingNode.front();
pendingNode.pop();
int numChild;
cout << "Enter number of children of " << front->data << endl;
cin >> numChild;
for (int i = 0; i < numChild; i++)
{
int childData;
cout << "Enter " << i << "th child of " << front->data << endl;
cin >> childData;
TreeNode<int> *child = new TreeNode<int>(childData);
front->children.push_back(child);
pendingNode.push(child);
}
}
return root;
}
int countLeafNodes(TreeNode<int> *root)
{
if (root = NULL)
{
return 0;
}
int total = 0;
if (root->children.size() == 0)
{
return 1;
}
for (int i = 0; i < root->children.size(); i++)
{
total += countLeafNodes(root->children[i]);
}
return total;
}
int main()
{
TreeNode<int> *root = takeInputLevelWise();
cout << "Total Leaf Nodes = " << countLeafNodes(root) << endl;
return 0;
}
I am pretty sure there is no problem with the TreeNode class or takeInputLevelWise() function as I have used the same code in many other questions to generate the tree. The problem must be in the countLeafNodes() function.

There is a problem in your countLeafNodes function.
if (root = NULL)
{
return 0;
}
Hope you find the error.

Related

How do I swap an element of a C++ stack

I have this task to do. Basically, I have to create a dynamic stack, then I have to choose an element and swap it with a new one which I inserted. The other elements remain the same and I have to display the new data. I've come to a dead end.
#include <iostream>
using namespace std;
struct elem
{
int key;
elem* next;
} *start = NULL, *p;
void push(int n);
int pop(int &n);
int main()
{
int num, counter = 0;
do
{
cout << "Input integers(!=0): ";
cin >> num;
if (num > 0 || num < 0)
{
push(num);
counter++;
}
}
while (num != 0);
cout << "\nStack: ";
while (pop(num))
cout << num << "\t";
cout << "\n";
int element, newValue;
cout << "Input element number: ";
cin >> element;
cout << "New value of element: ";
cin >> newValue;
here I struggle doing the swap
return 0;
}
void push(int n)
{
p = start;
start = new elem;
start->key = n;
start->next = p;
}
int pop(int &n)
{
if (start)
{
n = start->key;
p = start;
start = start->next;
delete p;
return 1;
}
else
return 0;
}
How do you swap a chosen one from a stack of (dinner) plates with the top one?
you pick the topmost, put it aside, then pick all the ones you don't want and put them on a new stack until you reach the chosen one. Pick it, exchange it with the original topmost one, put the chosen one aside.
Then re-stack, one by one, the plates from the new stack to the old one. Lastly, put the one you put aside on top.
Going through an intermediary stack like #Bathsheba suggested is the most straight forward solution here.
You can also save some execution time by simply modifying the "next" var of the previous
element to the element you're going the change.
#include <iostream>
using namespace std;
struct elem
{
int key;
elem* next;
}
*start = NULL, *p,*previous,*curr,*temp;
void push(int n);
int pop(int &n);
int main() {
int num, counter = 0;
do {
cout << "Input integers(!=0): ";
cin >> num;
if (num > 0 || num < 0) {
push(num);
counter++;
}
}
while (num != 0);
/* cout << "\nStack: ";
while (pop(num))
cout << num << "\t";
cout << "\n";
*/
int element, newValue;
cout << "Input element number: ";
cin >> element;
cout << "New value of element: ";
cin >> newValue;
curr = start ;
previous = NULL;
while(curr->next)
{
if(curr->key == element){
if(previous) {
temp = new elem;
temp->key = newValue;
temp->next = curr->next ;
previous->next = temp ;
break;
}
else {
temp = new elem;
temp->key = newValue;
temp->next = curr->next ;
start = temp ;
break;
}
}
else {
previous = curr ;
curr = curr->next;
}
}
while (pop(num))
cout << num << "\t";
cout << "\n";
return 0;
}
void push(int n) {
p = start;
start = new elem;
start->key = n;
start->next = p;
}
int pop(int &n) {
if (start) {
n = start->key;
p = start;
start = start->next;
delete p;
return 1;
}
else
return 0;
}

My C++ program returns EXC_BAD_ACCESS in Xcode ONLY

I made a program that involves a binary search tree. Basically, my segregates a set of input integers into "bins" in such a way that each bin are equal in value when their contents are summed.
#include <iostream>
#include <vector>
#ifndef DEBUG
#define DEBUG 0
#endif
using namespace std;
class Node {
private:
int weight = 0;
Node* leftNode;
Node* rightNode;
int bin = 0;
public:
Node() {}
Node(int weight) {
this->weight = weight;
}
void printContents() {
cout << weight << " ";
if(leftNode) leftNode->printContents();
if(rightNode) rightNode->printContents();
}
void addNode(Node* node) {
if(node->getWeight() <= this->weight) {
if(leftNode) leftNode->addNode(node);
else leftNode = node;
} else {
if(rightNode) rightNode->addNode(node);
else rightNode = node;
}
}
Node* getNode(int weight) {
if(!hasChildren()) {
if(this->weight == weight && bin == 0) return this;
else return nullptr;
} else {
Node* n = nullptr;
if(this->weight == weight && bin == 0) {
n = this;
}
Node* child;
if(leftNode && weight <= this->weight) {
child = leftNode->getNode(weight);
} else if(rightNode && weight > this->weight) {
child = rightNode->getNode(weight);
} else {
child = nullptr;
}
if(child) {
return child;
}
else return n;
}
}
bool hasChildren() {
if(leftNode || rightNode) return true;
else return false;
}
int getWeight() {
return weight;
}
void setBin(int bin) {
this->bin = bin;
}
int getBin() {
return bin;
}
void unbin() {
bin = 0;
}
void operator=(Node* node) {
this->weight = node->weight;
this->leftNode = node->leftNode;
this->rightNode = node->rightNode;
this->bin = node->bin;
}
};
class Bin {
private:
int binNum = 0;
int weight = 0;
int targetWeight = 0;
vector<Node*> nodes;
public:
Bin(int binNum, int targetWeight) {
this->binNum = binNum;
this->targetWeight = targetWeight;
}
void addNode(Node* node) {
weight += node->getWeight();
node->setBin(binNum);
nodes.push_back(node);
}
Node* removeLatestNode() {
Node* n = nodes.back();
weight -= n->getWeight();
nodes.pop_back();
n->unbin();
return n;
}
int getWeight() {
return weight;
}
bool isFull() {
if(weight == targetWeight) return true;
else return false;
}
bool willBeOverloaded(int x) {
if(weight + x > targetWeight) return true;
else return false;
}
};
void organize(Node* rootNode, int bins, int weightPerBin) {
#if DEBUG
cout << "Weight per bin: " << weightPerBin << endl;
#endif
for(int i = 1; i <= bins; i++) {
Bin bin(i, weightPerBin);
int x = weightPerBin;
while(!bin.isFull()) {
while(x > 0) {
Node* n = rootNode->getNode(x);
if (n) {
#if DEBUG
cout << "bin " << i << " : ";
cout << n->getWeight() << endl;
#endif
if (!bin.willBeOverloaded(n->getWeight())) {
#if DEBUG
cout << "adding to bin " << i << " : " << n->getWeight() << endl;
#endif
bin.addNode(n);
x = weightPerBin - bin.getWeight();
if(bin.isFull()) break;
} else {
x--;
}
} else {
x--;
}
}
if(!bin.isFull()) {
Node* n = bin.removeLatestNode();
#if DEBUG
cout << "removing from bin " << i << " : " << n->getWeight() << endl;
#endif
x = n->getWeight() - 1;
}
}
}
}
int getWeightPerBin(int* weights, int n, int bins) {
int weight = 0;
for(int i = 0; i < n; i++) {
weight += weights[i];
}
return weight/bins;
}
int main() {
int n;
int *weights;
int bins;
cin >> n;
weights = new int[n];
for(int i = 0; i < n; i++)
cin >> weights[i];
cin >> bins;
Node nodes[n];
nodes[0] = new Node(weights[0]); //the root node
for(int i = 1; i < n; i++) {
nodes[i] = new Node(weights[i]);
nodes[0].addNode(&nodes[i]);
}
organize(&nodes[0], bins, getWeightPerBin(weights, n, bins));
for(int i = 0; i < n; i++) {
cout << nodes[i].getBin() << " ";
}
return 0;
}
I developed this program in CLion IDE and it works perfectly. Recently I discovered that Xcode can also be used to develop C++ programs so I tried using it with the exact same code. But when I run the program, it always returns:
xcode error screenshot
It returns an error called EXC_BAD_ACCESS which is the first time I've encountered it. I'm a student who has a good background in Java and is currently learning C++ for a class. My knowledge in C++ is limited and I'd like to know whether this problem is due to Xcode or is inherent in my code.
You don't initialize leftNode and rightNode - they are not magically initialized to nullptr, so calling a function like
void printContents() {
cout << weight << " ";
if(leftNode) leftNode->printContents();
if(rightNode) rightNode->printContents();
}
will have Undefined Behaviour.
I suggest you initialize your variables before using them.

How to Visit Each Node in Chained Hash Table Linked Lists

I am writing chained hash table code.
I do not understand why my linked list traversal does not stop at NULL when I set entry->next->next = NULL after I insert.
I have omitted code which is not useful for my question:
What is causing the linked list traversal in `printTable' to loop forever?
ChainHash.h:
class Entry {
private:
string key;
int value;
Entry *next;
friend class HashTable_CH;
public:
Entry(string k, int v) {
key = k;
value = v;
next = NULL;
}
};
class HashTable_CH {
private:
Entry **slots;
const int DEFAULT_CAP = 11;
const float load_factor = 0.5;
int capacity;
int size;
//int isPrime(int n) {
//int calculateGrowSize() {
int hash(string k) {
int c = 0;
for (int i = 0; i < k.length(); i++)
c += int(k[i]);
return c % capacity;
}
//int probe(int hash, int index) {
public:
HashTable_CH() {
slots = new Entry*[DEFAULT_CAP];
capacity = DEFAULT_CAP;
size = 0;
for (int i = 0; i < DEFAULT_CAP; i++)
slots[i] = NULL;
}
void Insert(string key, int value) {
if (float(size) / float(capacity) >= load_factor)
//grow();
return;
int h = hash(key);
if (slots[h] == NULL) {
slots[h] = new Entry(key, value);
size++;
return;
} else {
Entry *entry = slots[h];
while (entry->next != NULL)
entry = entry->next;
entry->next = new Entry(key, value);
entry->next->next = NULL;
}
}
//bool Search(string, int &value) {
//void Remove(string key) {
void printTable() {
for (int i = 0; i < capacity; i++) {
cout << "Slot " << i << ": ";
if (slots[i] == NULL)
cout << "*****";
else {
Entry **temp = slots;
while (temp != NULL) {
cout << "Key: " << slots[i]->key << ", " << slots[i]->value;
}
}
} cout << "\n";
} cout << "\n";
}
};
testChainedHash.cpp:
#include"ChainHash.h"
int main() {
HashTable_CH t1;
t1.Insert("froyo", 500);
t1.Insert("froyo", 600);
t1.Insert("froyo", 700);
t1.printTable();
}
Here:
while (temp != NULL) {
cout << "Key: " << slots[i]->key << ", " << slots[i]->value;
}
Do you see the problem?

c++ Stuck making an binary tree implementation with an array and lists

I am working on writing a list of children binary tree implementation. In my code I have an array of lists. Each list contains a node followed by its children on the tree. I finished writing the code and everything compiled, but I keep getting a segmentation fault error and I cannot figure out why. I have been attempting to debug and figure out where my code messes up. I know that there is an issue with the FIRST function. It causes a segmentation fault. Also, when I try to print just one of the lists of the array, it prints everything. I have been stuck on this for a very long time now and would like some help. Can anyone offer suggestions as to why the FIRST and PRINT functions are not working? Maybe there is a large error that I just cannot see.
My code is as follows:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <array>
#include <string.h>
using namespace std;
struct node
{
char element;
struct node *next;
}*start;
class list
{
public:
void ADD(char n);
node* CREATE(char n);
void BEGIN(char n);
char FIRST();
char END();
char NEXT(char n);
char PREVIOUS(char n);
int LOCATE(char n);
void EMPTY();
void PRINT();
list()
{
start = NULL;
}
};
char PARENT(const char n, list tree[], int length)
{
int i=0;
list l;
for (i; i<length; i++)
{
l = tree[i];
if (n != l.FIRST())
{
if (l.LOCATE(n)>0)
return l.FIRST();
}
}
}
char LEFTMOST_CHILD(char n, list tree[], int length)
{
int i;
list l;
for (i=0; i<length; i++)
{
l = tree[i];
if (l.FIRST() == n)
return l.NEXT(n);
}
}
char RIGHT_SIBLING(char n, list tree[], int length)
{
int i;
list l;
for (i=0; i<length; i++)
{
l = tree[i];
if(n != l.FIRST())
{
if (l.LOCATE(n) > 0)
{
return l.NEXT(n);
}
}
}
}
char ROOT(list tree[]) //assumes array is in order, root is first item
{
list l;
l = tree[0];
cout << "Assigned tree to l" << endl;
return l.FIRST();
}
void MAKENULL(list tree[], int length)
{
int i;
list l;
for (i=0; i<length; i++)
{
l = tree[i];
l.EMPTY();
}
}
void list::PRINT()
{
struct node *temp;
if (start == NULL)
{
cout << "The list is empty" << endl;
return;
}
temp = start;
cout << "The list is: " << endl;
while (temp != NULL)
{
cout << temp->element << "->" ;
temp = temp->next;
}
cout << "NULL" << endl << endl;
}
void list::EMPTY()
{
struct node *s, *n;
s = start;
while (s != NULL)
{
n = s->next;
free(s);
s = n;
}
start = NULL;
}
int list::LOCATE(char n)
{
int pos = 0;
bool flag = false;
struct node *s;
s = start;
while (s != NULL)
{
pos++;
if (s->element == n)
{
flag == true;
return pos;
}
s = s->next;
}
if (!flag)
return -1;
}
void list::ADD(char n)
{
struct node *temp, *s;
temp = CREATE(n);
s = start;
while (s->next != NULL)
s = s->next;
temp->next = NULL;
s->next = temp;
}
node *list::CREATE(char n)
{
struct node *temp;
temp = new(struct node);
temp->element = n;
temp->next = NULL;
return temp;
}
void list::BEGIN(char n)
{
struct node *temp, *p;
temp = CREATE(n);
if (start == NULL)
{
start = temp;
start->next = NULL;
}
}
char list::FIRST()
{
char n;
struct node *s;
s = start;
cout << "s = start" << endl;
n = s->element;
cout << "n" << endl;
return n;
}
char list::END()
{
struct node *s;
s = start;
int n;
while (s != NULL)
{
n = s->element;
s = s->next;
}
return n;
}
char list::NEXT(char n)
{
char next;
struct node *s;
s = start;
while (s != NULL)
{
if (s->element == n)
break;
s = s->next;
}
s = s->next;
next = s->element;
return next;
}
char list::PREVIOUS(char n)
{
char previous;
struct node *s;
s = start;
while (s != NULL)
{
previous = s->element;
s = s->next;
if (s->element == n)
break;
}
return previous;
}
main()
{
list a,b,c,d,e,f,g,h,i,j,k,l,m,n;
a.BEGIN('A');
b.BEGIN('B');
c.BEGIN('C');
d.BEGIN('D');
e.BEGIN('E');
f.BEGIN('F');
g.BEGIN('G');
h.BEGIN('H');
i.BEGIN('I');
j.BEGIN('J');
k.BEGIN('K');
l.BEGIN('L');
m.BEGIN('M');
n.BEGIN('N');
a.ADD('B');
a.ADD('C');
b.ADD('D');
b.ADD('E');
e.ADD('I');
i.ADD('M');
i.ADD('N');
c.ADD('F');
c.ADD('G');
c.ADD('H');
g.ADD('J');
g.ADD('K');
h.ADD('L');
a.PRINT();
list tree[] = {a,b,c,d,e,f,g,h,i,j,k,l,m,n};
int length = sizeof(tree)/sizeof(char);
char root = ROOT(tree);
cout << "Found root" << endl;
char parent = PARENT('G', tree, length);
cout << "Found Parent" << endl;
char leftChild = LEFTMOST_CHILD('C', tree, length);
cout << "found left child" << endl;
char rightSibling = RIGHT_SIBLING('D', tree, length);
cout << "found right sibling" << endl;
cout << "The root of the tree is: ";
cout << root << endl;
cout << "The parent of G is: ";
cout << parent << endl;
cout << "The leftmost child of C is" ;
cout << leftChild << endl;
cout << "The right sibling of D is: " ;
cout << rightSibling << endl;
}
Any help will be very appreciated. Thanks you!
The fundamental problem is that you have written a lot of code before testing any of it. When you write code, start with something small and simple that works perfectly, add complexity a little at a time, test at every step, and never add to code that doesn't work.
The specific problem (or at least one fatal problem) is here:
struct node
{
char element;
struct node *next;
}*start;
class list
{
public:
//...
list()
{
start = NULL;
}
};
The variable start is a global variable. The class list has no member variables, but uses the global variable. It sets start to NULL every time a list is constructed, and every list messes with the same pointer. The function FIRST dereferences a pointer without checking whether the pointer is NULL, and when it is, you get Undefined Behavior.
It's not entirely clear what you intended, but you seem to misunderstand how variables work in C++.

Reversing a singly-linked list in C++

I am having an issue with my attempt at recursively reversing my implementation of a singly-linked list.
I have read other similar questions regarding this process, however, in my attempt at implementing this process in my own program, I've come up short.
This is my attempt below (which is slightly different than what is presented in the code that follows thereafter):
Note: My list uses a root pointer which holds no significant data, and serves only as an address with which to reference data in the list.
void IntList::reverse(Node* t_node) {
if(t_node == NULL) {
reverse(root);
} else
if(t_node->next == NULL) {
cout << "In (swapping): " << t_node->value << endl;
root->next = t_node;
} else {
cout << "In: " << t_node->value << endl;
Node* tmp = t_node->next;
reverse(t_node->next);
tmp->next = t_node;
}
return NULL;
}
I lose reference somewhere and print endlessly when trying to display the list. I am really at a loss as to what the error I've made is, but suspect it may have something to do with how I handle my root.
Here is the program in its entirety (all functioning apart from the reverse() methods) for completeness.
#ifndef INTLIST_H
#define INTLIST_H
#include<iostream>
using namespace std;
class IntList {
private:
struct Node {
int value;
Node* next;
};
int size;
Node* root;
void destroy();
public:
IntList() { root = new Node; root->next = 0; root-> value = 0; size = 0;}
IntList(const IntList& list) { this->root = list.root; this->size = list.size; }
~IntList() {}
void appendNode(int val);
void insertNode(int pos, int val);
void deleteNode(int pos);
int searchNode(int val);
int getSize() const;
void print() const;
Node* reverse(Node* t_node);
int &operator[](int element) const;
void pop_back();
void pop_front();
void push_back(int val);
void push_front(int val);
};
void IntList::appendNode(int val) {
push_back(val);
}
void IntList::insertNode(int pos, int val) {
Node* tmp;
Node* current = root;
for(int i = 0; i < pos && current->next != NULL; i++) {
current = current->next;
}
tmp = new Node;
tmp->value = val;
tmp->next = current->next;
current->next = tmp;
size++;
}
void IntList::deleteNode(int pos) {
Node* tmp;
Node* current = root;
if(pos <= size-1) {
for(int i = 0; i < pos; i++) {
current = current->next;
}
tmp = current->next;
current->next = tmp->next;
delete tmp;
size--;
} else {
cout << "ERROR: Out of range." << endl;
}
}
int IntList::searchNode(int val) {
int position = 0;
Node* current = root->next;
if(size != 0) {
for(position = 0; position < size && current->value != val; position++) {
current = current->next;
}
} else {
cout << "ERROR: List is empty." << endl;
position = -1;
}
return position;
}
int IntList::getSize() const {
return size;
}
void IntList::print() const {
Node* current = root->next;
cout << "List: ";
while(current != NULL) {
cout << current->value << " ";
current = current->next;
}
if(getSize() == 0) {
cout << "Empty.";
}
cout << endl;
}
IntList::Node* IntList::reverse(Node* t_node) {
#define REVERSE
#ifndef REVERSE
if(t_node == NULL) {
reverse(root);
} else
if(t_node->next == NULL) {
cout << "In (swapping): " << t_node->value << endl;
root->next = t_node;
} else {
cout << "In: " << t_node->value << endl;
Node* tmp = t_node->next;
reverse(t_node->next);
tmp->next = t_node;
}
#endif //reverses list, but causes infinite loop in display
return NULL;
}
int &IntList::operator[](int pos) const {
Node* current = root->next;
if(pos <= size-1) {
for(int i = 0; i < pos; i++) {
current = current->next;
}
} else {
cout << "ERROR: Out of bounds.";
current = NULL;
}
return current->value;
}
void IntList::pop_back() {
deleteNode(size-1);
}
void IntList::pop_front() {
deleteNode(0);
}
void IntList::push_back(int val) {
insertNode(size, val);
}
void IntList::push_front(int val) {
insertNode(0, val);
}
#endif
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>
using namespace std;
template<typename T>
class LinkedList {
private:
struct Node {
T value;
Node* next;
};
int size;
Node* root;
void destroy();
public:
LinkedList() { root = new Node; root->next = 0; root-> value = 0; size = 0;}
LinkedList(const LinkedList &) {}
~LinkedList() {}
void appendNode(T val);
void insertNode(int pos, T val);
void deleteNode(int pos);
int searchNode(T val);
int getSize() const;
void print() const;
void reverse(Node* t_node);
int &operator[](int element) const;
void pop_back();
void pop_front();
void push_back(T val);
void push_front(T val);
};
template <typename T>
void LinkedList<T>::appendNode(T val) {
push_back(val);
}
template <typename T>
void LinkedList<T>::insertNode(int pos, T val) {
Node* tmp;
Node* current = root;
for(int i = 0; i < pos && current->next != NULL; i++) {
current = current->next;
}
tmp = new Node;
tmp->value = val;
tmp->next = current->next;
current->next = tmp;
size++;
}
template <typename T>
void LinkedList<T>::deleteNode(int pos) {
Node* tmp;
Node* current = root;
if(pos <= size-1) {
for(int i = 0; i < pos; i++) {
current = current->next;
}
tmp = current->next;
current->next = tmp->next;
delete tmp;
size--;
} else {
cout << "ERROR: Out of range." << endl;
}
}
template <typename T>
int LinkedList<T>::searchNode(T val) {
int position = 0;
Node* current = root->next;
if(size != 0) {
for(position = 0; position < size && current->value != val; position++) {
current = current->next;
}
} else {
cout << "ERROR: List is empty." << endl;
position = -1;
}
return position;
}
template <typename T>
int LinkedList<T>::getSize() const {
return size;
}
template <typename T>
void LinkedList<T>::print() const {
Node* current = root->next;
cout << "List: ";
while(current != NULL) {
cout << current->value << " ";
current = current->next;
}
if(getSize() == 0) {
cout << "Empty.";
}
cout << endl;
}
template <typename T>
void LinkedList<T>::reverse(Node* t_node) {
/*
if(t_node == NULL) {
reverse(root);
} else
if(t_node->next == NULL) {
cout << "In (swapping): " << t_node->value << endl;
root->next = t_node;
} else {
cout << "In: " << t_node->value << endl;
Node* tmp = t_node->next;
reverse(t_node->next);
tmp->next = t_node;
}
*/ //reverses list, but causes infinite loop in display
}
template <typename T>
int &LinkedList<T>::operator[](int pos) const {
Node* current = root->next;
if(pos <= size-1) {
for(int i = 0; i < pos; i++) {
current = current->next;
}
} else {
cout << "ERROR: Out of bounds.";
current = NULL;
}
return current->value;
}
template <typename T>
void LinkedList<T>::pop_back() {
deleteNode(size-1);
}
template <typename T>
void LinkedList<T>::pop_front() {
deleteNode(0);
}
template <typename T>
void LinkedList<T>::push_back(T val) {
insertNode(size, val);
}
template <typename T>
void LinkedList<T>::push_front(T val) {
insertNode(0, val);
}
#endif
//test driver
int main() {
IntList i_list;
int n;
cout << "Appending node: value = " << 0 << endl;
i_list.appendNode(0);
i_list.print();
cout << endl;
n = 5;
cout << "Inserting nodes (at their values). Node values = { ";
for(int i = 0; i < n; i++) {
cout << i << " ";
i_list.insertNode(i,i);
}
cout << "}" << endl;
i_list.print();
cout << endl;
cout << "Deleting node at position: " << i_list.getSize()-1 << endl;
i_list.deleteNode(i_list.getSize()-1);
i_list.print();
cout << endl;
cout << "Searching for value: " << 3 << endl;
cout << "Found at: " << i_list.searchNode(3) << endl;
cout << endl;
i_list.print();
cout << "List size: " << i_list.getSize() << endl;
cout << endl;
n = 3;
cout << "Calling node at list[" << n << "]: " << i_list[n] << endl;
cout << endl;
i_list.print();
cout << "Deleting node from back position." << endl;
i_list.pop_back();
i_list.print();
cout << endl;
i_list.print();
cout << "Deleting node from front position." << endl;
i_list.pop_front();
i_list.print();
cout << endl;
n = 9;
i_list.print();
cout << "Adding node (value = " << n << ") to back position." << endl;
i_list.push_back(n);
i_list.print();
cout << endl;
n = 8;
i_list.print();
cout << "Adding node (value = " << n << ") to front position." << endl;
i_list.push_front(n);
i_list.print();
cout << endl;
i_list.print();
cout << "Copying list to new list." << endl;
IntList t_list(i_list);
cout << endl;
cout << "List copy:" << endl;
t_list.print();
cout << endl;
/*
* Showing functionality transfers over to LinkedList template class
* generally, for primitive data types (lacks absolutely generality
* for data which can't be passed directly to cout).
*/
cout << "List functionality transfers generally to LinkedList class:" << endl;
LinkedList<int> int_list;
LinkedList<double> double_list;
LinkedList<char> char_list;
cout << "Appending nodes:" << endl;
n = 5;
for(int i = 0; i < n; i++){
int_list.appendNode(i);
}
int_list.print();
n = 5;
for(int i = 0; i < n; i++){
double_list.appendNode(i+0.1);
}
double_list.print();
n = 5;
for(int i = 0; i < n; i++){
char_list.appendNode('A' + i);
}
char_list.print();
cout << "Removing nodes:" << endl;
n = 5;
for(int i = 0; i < n; i++){
int_list.pop_back();
}
int_list.print();
n = 5;
for(int i = 0; i < n; i++){
double_list.pop_back();
}
double_list.print();
n = 5;
for(int i = 0; i < n; i++){
char_list.pop_back();
}
char_list.print();
return 0;
}
EDIT: I've revised my algorithm, and I believe it works algorithmically, but functionally it may be doing something which is causing a memory issue. I'm not sure as to why that may be, but here it is:
void IntList::reverse() {
IntList tmp(*this);
int list_size = size;
for(int i = 0; i < list_size; i++) {
this->insertNode(i, tmp[tmp.getSize()-1]);
this->pop_back();
tmp.pop_back();
}
}
In fact, if my [] operator overload were functioning within this method (which for some reason it is not?) I could do away with the tmp list and just reference the last value in the list directly as this[size-1].
What is the issue here?
Your problem is that after the reverse() the last element in your list will point to the root element instead of pointing to null. One solution could be an explicit check for that condition so you would get:
void IntList::reverse(Node* t_node) {
if(t_node == NULL) {
reverse(root);
return;
}
if(t_node->next == NULL) {
cout << "In (swapping): " << t_node->value << endl;
root->next = t_node;
} else {
cout << "In: " << t_node->value << endl;
Node* tmp = t_node->next;
reverse(t_node->next);
// If this node was the first node it will now be the last
if (t_node == root) {
tmp->next = NULL;
} else {
tmp->next = t_node;
}
}
}
That doesn't work if it should be possible to reverse a subpart of the list though. If that is something you need, then you probably need to use a helper function which handles all elements but the first one.
Suppose we have the IntList {1,2,3}, which actually has this form:
0 -> 1 -> 2 -> 3
Then we call reverse(root), so that t_node has the same value as root (and therefore points to (0)).
Node* tmp = t_node->next;
So tmp points to (1).
reverse(t_node->next);
Suppose this works, and the list is now 0->1->3->2
tmp->next = t_node;
So now 1->0. The list is now a loop, and the other nodes have been lost.
It is not clear what you intended this function to do, but you must have misunderstood something.
EDIT: You are attempting a high-level solution when you do not understand the low-level mechanics.
Your copy constructor:
IntList(const IntList& list) { this->root = list.root; this->size = list.size; }
performs what we call a "shallow copy"; it copies the pointer members, but not the things they point to. If you have a list A that looks like this:
0->1->2->3
and then call IntList B(A);, you'll get something that looks like this:
0
|
v
0->1->2->3
If you then call A.pop_back() and B.pop_back(), what do you think will happen?
And more to the point, what are you trying to do? Do you want to know how to write a recursive function, or is that no longer necessary?