Bug in AVL tree code, data structures c++ - c++

I am really trying to figure out the bug in my code I wrote for AVL tree but there seems to be a bug in it.
It calls the rotation functions but when it finishes rotation there are several problem:
root doesn't change
only root value is displayed when in-order traversal is done, other values seem to disappear
I have been trying to fix this bug since 2-3 days but cant seem to solve it.
Would love some help from you guys. I will be attaching the code with this.
/*
insertion
rotations all DONE
level order DONE
deletion
*/
#include <iostream>
#include <queue>
using namespace std;
struct node
{
int data;
int height;
node *left;
node *right;
node()
{
height = 0;
left = right = NULL;
}
};
class AVL
{
public:
node *root;
AVL()
{
root = NULL;
}
// search function
bool search(int num)
{
node *nodePtr = root;
if (root->data == num)
{
cout << "FOUND " << endl;
return true;
}
else
{
while (nodePtr != NULL)
{
if (nodePtr->data < num)
{
nodePtr = nodePtr->right;
}
else if (nodePtr->data > num)
{
nodePtr = nodePtr->left;
}
else
{
cout << "FOUND " << endl;
return true;
}
}
cout << "NOT FOUND " << endl;
return false;
}
}
// inorder
void inorder()
{
inorder(root);
}
// postorder
void postorder()
{
postorder(root);
}
// preorder
void preorder()
{
preorder(root);
}
// inorder utility function
void inorder(node *&nodePtr)
{
if (nodePtr)
{
inorder(nodePtr->left);
cout << nodePtr->data << ", ";
inorder(nodePtr->right);
}
}
// preorder utility function
void preorder(node *&nodePtr)
{
if (nodePtr)
{
cout << nodePtr->data << ", ";
preorder(nodePtr->left);
preorder(nodePtr->right);
}
}
// postorder utility function
void postorder(node *&nodePtr)
{
if (nodePtr)
{
postorder(nodePtr->left);
postorder(nodePtr->right);
cout << nodePtr->data << ", ";
}
}
// returns the number of nodes in the tree
int size(node *&nodePtr)
{
if (!nodePtr)
{
return 0;
}
else
{
return (size(nodePtr->left) + size(nodePtr->right)) + 1;
}
}
// function to check if tree is empty or not
bool isempty()
{
if (root == NULL)
{
return true;
}
else
{
return false;
}
}
// max function to calculate height and also the balance factor
int maximum(int x, int y)
{
if (x>y)
{
return x;
}
else
{
return y;
}
}
// returns the level of the tree
int returnHeight(node *&nodePtr)
{
if (nodePtr == NULL)
{
return 0;
}
else
{
return nodePtr->height;
}
}
// assigning the height to the node
void assignHeightToNode(node *&nodePtr)
{
int left = returnHeight(nodePtr->left);
int right = returnHeight(nodePtr->right);
nodePtr->height = maximum(left, right) + 1;
}
// single left rotate
node *singleLeftRotate(node *&nodePtr)
{
// if (nodePtr==NULL)
// {
// return;
// }
node * b = nodePtr->right;
nodePtr->right = b->left;
b->left = nodePtr;
return b;
}
// single right rotate
node *singleRightRotate(node *&nodePtr)
{
// if (nodePtr==NULL)
// {
// return ;
// }
node * b = nodePtr->left;
nodePtr->left = b->right;
b->right = nodePtr;
assignHeightToNode(nodePtr);
assignHeightToNode(b);
return b;
}
// double left rotate
node *doubleLeft(node *&nodePtr)
{
nodePtr->right = singleRightRotate(nodePtr->right);
return singleLeftRotate(nodePtr);
}
// double right rotate
node *doubleRight(node *&nodePtr)
{
nodePtr->left = singleLeftRotate(nodePtr->left);
return singleRightRotate(nodePtr);
}
// insert function
void insert1(int x)
{
cout << "NOW INSERTING " << x << endl;
insert2(x, root);
}
// insert utility function
void insert2(int &x, node *&nodePtr)
{
if (nodePtr == NULL)
{
node *newNode = new node;
newNode->data = x;
newNode->height = 0;
nodePtr = newNode;
checkRotations(nodePtr, x);
return;
}
else
{
if (x < nodePtr->data)
{
cout << endl << "GOING LEFT " << endl;
insert2(x, nodePtr->left);
}
else if (x > nodePtr->data)
{
cout << endl << "GOING RIGHT " << endl;
insert2(x, nodePtr->right);
}
else if (nodePtr->data == x)
{
cout << "DUPLICATE VALUES NOT ALLOWED " << endl;
return;
}
}
checkRotations(nodePtr, x);
}
// checking if rotations needed
void checkRotations(node *&nodePtr, int &x)
{
assignHeightToNode(nodePtr);
cout << endl << endl << "HEIGHT OF " << nodePtr->data << " IS " << nodePtr->height << endl;
int bf = returnHeight(nodePtr->left) - returnHeight(nodePtr->right);
cout << endl << endl << "BALANCE FACTOR AT NODE " << nodePtr->data << " IS " << bf << endl;
if (bf < -1 || bf > 1)
{
cout << endl << endl << "ROTATION IS HAPPEENING " << endl << endl;
if (x > nodePtr->data)
{
singleLeftRotate(nodePtr);
cout << endl << "ROTATION DONE SINGLE LEFT " << endl;
return;
}
else if (x < nodePtr->data)
{
singleRightRotate(nodePtr);
cout << endl << "ROTATION DONE SINGLE RIGHT " << endl;
return;
}
else if (x < root->data && x > root->left->data)
{
doubleRight(nodePtr);
cout << endl << "ROTATION DONE DOUBLE LEFT " << endl;
return;
}
else if (x > root->data && x < root->right->data)
{
doubleLeft(nodePtr);
cout << endl << "ROTATION DONE DOUBLE LEFT " << endl;
return;
}
}
}
// level order display code
void levelOrderDisplay()
{
levelOrderDisplay2(root);
}
// level order display utility function
void levelOrderDisplay2(node *&nodePtr)
{
if (nodePtr == NULL)
{
cout << "THE TREE IS EMPTY" << endl;
return;
}
queue <node *> displayer;
displayer.push(nodePtr);
while (!displayer.empty())
{
node *currentNode = displayer.front();
cout << currentNode->data << ", ";
if (currentNode->left != NULL)
{
displayer.push(currentNode->left);
}
else if (currentNode->right != NULL)
{
displayer.push(currentNode->right);
}
displayer.pop();
}
}
void rootD()
{
cout << "root is " << root->data << endl;
}
};
int main()
{
AVL tree;
tree.insert1(3);
tree.insert1(2);
tree.insert1(1);
tree.insert1(4);
tree.insert1(5);
tree.insert1(6);
tree.insert1(7);
tree.inorder();
// tree.rootD();
// tree.levelOrderDisplay();
// tree.rootD();
return 0;
}

I suggest you that do not pass node pointer by reference where your code does not change pointer value such as print. Try this... I completed my avl tree code just 2 3 day before and i have similar problem, when i debug my program i came to know that somehow in print function my pointer value is changed because i passed it by reference..... So.. Try this and see if work or not.... Hope this might help you.

Really late answer, but this is what you had to do. You should set the node passed in the function equal to the temporary node made in the function. In coding language, nodePtr=b should have been the last line of the single rotate functions.
Hope this helps :)

Related

I m not getting correct output for pre and post order

// in this code I first created nodes stored them in a que and keep on removing them as I entered their left and right children. To make a node have no further children I entered -1 while entering data. Here I am not able to understand what is wrong with my code , I am getting wrong output for preorder and postorder traversals. It would be really great if you guys could help me out.
I made a class que for queue ds and inherited it in tree class in protected mode.
#include <iostream>
#include <math.h>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
class que
{
protected:
int start;
int end;
struct node **arr;
int n;
public:
que(int x)
{
n = x;
arr = new struct node *[n];
start = -1;
end = -1;
}
void isfull()
{
if (end == n)
cout << "Queue is full !!!" << endl;
return;
}
int isempty()
{
if (start == end)
{
start = -1;
end = -1;
cout << "Queue is empty !!!" << endl;
return 1;
}
return 0;
}
void enqu(struct node *x)
{
if (end == n)
{
cout << "called" << endl;
isfull();
return;
}
end++;
arr[end] = x;
}
struct node *dequ(void)
{
struct node *q = 0;
if (start == end)
{
isempty();
return q;
}
start++;
cout << "Element removed is ->" << arr[start] << endl;
return arr[start];
}
};
class tree : protected que
{
public:
struct node *head;
struct node *ptr;
tree(int n) : que(n)
{
head = 0;
ptr = 0;
enter();
}
void create(void)
{
ptr = new struct node;
ptr->left = 0;
ptr->right = 0;
}
void enter(void)
{
struct node *p;
if (head == 0)
{
create();
cout << "Enter root element of tree -> ";
cin >> ptr->data;
head = ptr;
cout << "Enquing ptr - " << ptr << endl;
enqu(ptr);
}
while (!isempty())
{
p = dequ();
cout << "Enter left child ->";
int x;
cin >> x;
if (x != -1)
{
create();
p->left = ptr;
ptr->data = x;
cout << "Enquing ptr - " << ptr << endl;
enqu(ptr);
}
cout << "Enter right child ->";
cin >> x;
if (x != -1)
{
create();
p->right = ptr;
ptr->data = x;
cout << "Enquing ptr - " << ptr << endl;
enqu(ptr);
}
}
}
void inorder(struct node *yes)
{
if (yes != 0)
{
inorder(yes->left);
cout << "--> " << yes->data << endl;
inorder(yes->right);
}
}
void preorder(struct node *yes)
{
if (yes != 0)
{
cout << "--> " << yes->data << endl;
inorder(yes->left);
inorder(yes->right);
}
}
void postorder(struct node *yes)
{
if (yes != 0)
{
inorder(yes->left);
inorder(yes->right);
cout << "--> " << yes->data << endl;
}
}
int count(struct node *yes)
{
static int x = 0, y = 0;
if (yes == 0)
return 0;
x = count(yes->left);
y = count(yes->right);
return x + y + 1;
}
int height(struct node *yes)
{
static int a = 0, b = 0;
if (yes == 0)
return 0;
a = count(yes->left);
b = count(yes->right);
if (a > b)
return a + 1;
else
return b + 1;
}
};
int main()
{
int x;
cout << "Enter height of tree - ";
cin >> x;
int max = 0;
max = pow(2, x + 1) - 1;
tree tr(max);
cout << "Preorder traversal -- " << endl;
tr.preorder(tr.head);
cout << "Inorder traversal -- " << endl;
tr.inorder(tr.head);
cout << "Postorder traversal -- " << endl;
tr.postorder(tr.head);
cout << "\n No. of elements -- " << tr.count(tr.head);
cout << "\n Height of tree --" << tr.height(tr.head);
}
The preorder and postorder functions doesn't call themselves recursively. Instead they call the inorder function, which will lead to all but the root will be printed using inorder.

C++ Sorted Doubly Linked List: Problems inserting in middle of list

below is my current in-progress code converting a singly linked to a doubly linked list. I haven't touched the delete function yet. I've gotten insert in empty list, end of list, and beginning of list apparently working.
However nodes inserting in the middle seemingly fail to create a link to the previous node. My debugging lines I inserted seem to show both the n->next and n-> prev with the correct memory address, but when I go to reverseprint, any nodes inserted in the middle are missed and the links are gone. Where am I going wrong in regards to this?
Code below:
#include <iostream>
#include <string>
using namespace std;
// define a node for storage and linking
class node {
public:
string name;
node *next;
node *prev;
};
class linkedList {
public:
linkedList() :top(NULL) {}
bool empty() { return top == NULL; }
node *getTop() { return top; }
node *getEnd() { return end; }
void setTop(node *n) { top = n; }
void setEnd(node *p) { end = p; }
void add(string);
int menu();
void remove(string);
~linkedList();
void reversePrint();
friend ostream& operator << (ostream&, const linkedList&); // default output is in-order print.
private:
node *top;
node *end;
};
void main() {
linkedList l;
cout << l.empty() << endl;
int option = 0;
string s;
bool go = true;
while (go) {
option = l.menu();
switch (option) {
case 1: cout << "enter a name: "; cin >> s; l.add(s); break;
case 2: cout << "enter name to be deleted: "; cin >> s; l.remove(s); break;
case 3: cout << l; break;
//case 4: cout << "can not be done with a singly linked list" << endl;
case 4: l.reversePrint(); break;
case 5: cout << "exiting" << endl; go = false; break;
}
}
system("pause");
}
void linkedList::remove(string s) {
bool found = false;
node *curr = getTop(), *prev = NULL;
while (curr != NULL) {
// match found, delete
if (curr->name == s) {
found = true;
// found at top
if (prev == NULL) {
node *temp = getTop();
setTop(curr->next);
delete(temp);
// found in list - not top
}
else {
prev->next = curr->next;
delete(curr);
}
}
// not found, advance pointers
if (!found) {
prev = curr;
curr = curr->next;
}
// found, exit loop
else curr = NULL;
}
if (found)cout << "Deleted " << s << endl;
else cout << s << " Not Found " << endl;
}
void linkedList::add(string s) {
node *n = new node();
n->name = s;
n->next = NULL;
n->prev = NULL;
// take care of empty list case
if (empty()) {
top = n;
end = n;
// take care of node belongs at beginning case
}
else if (getTop()->name > s) {
n->next = getTop();
n->prev = NULL;
setTop(n);
node *temp;
temp = n->next;
temp->prev = n;
// take care of inorder and end insert
}
else {
// insert in order case
node *curr = getTop(), *prev = curr;
while (curr != NULL) {
if (curr->name > s)break;
prev = curr;
curr = curr->next;
}
if (curr != NULL) { // search found insert point
n->next = curr;
cout << n->name << " " << n << " prev " << prev << " " << prev->name << endl;
n->prev = prev;
prev->next = n;
cout << "n->prev is: " << n->prev << " " << n->prev->name << endl;
cout << "n->next is: " << n->next << " " << n->next->name << endl;
}
// take care of end of list insertion
else if (curr == NULL) {// search did not find insert point
prev->next = n;
n->prev = prev;
cout << "n->prev is: " << n->prev << " " << n->prev->name << endl;
setEnd(n);
}
}
}
ostream& operator << (ostream& os, const linkedList& ll) {
//linkedList x = ll; // put this in and the code blows up - why?
node *n = ll.top;
if (n == NULL)cout << "List is empty." << endl;
else
while (n != NULL) {
os << n->name << endl;
os << n << endl;
if (n->next != NULL) {
os << "next is " << n->next << endl;
}
n = n->next;
}
return os;
}
void linkedList::reversePrint() {
node *n = end;
if (n == NULL)cout << "List is empty." << endl;
else
while (n != NULL) {
//cout << n->name << endl;
cout << "memory address of " << n->name << " is " << n << endl;
if (n->prev != NULL) {
cout << "prev is " << n->prev << endl;
}
n = n->prev;
}
return;
}
// return memory to heap
linkedList::~linkedList() {
cout << "~linkedList called." << endl;
node *curr = getTop(), *del;
while (curr != NULL) {
del = curr;
curr = curr->next;
delete(del);
}
}
int linkedList::menu() {
int choice = 0;
while (choice < 1 || choice > 5) {
cout << "\nEnter your choice" << endl;
cout << " 1. Add a name." << endl;
cout << " 2. Delete a name." << endl;
cout << " 3. Show list." << endl;
cout << " 4. Show reverse list. " << endl;
cout << " 5. EXIT " << endl;
cin >> choice;
}
return choice;
}
You are not setting the prev of the current in insertion into middle, just do:
n->next = curr;
curr->prev = n; // <-- this

AVL Tree Rotation Deletes Nodes

Working on AVL implementation. When I try to perform a rotation it deletes the children of the node being rotated. So far I've only started on right. I didn't implement a parent pointer in my nodes as I used my BST as a base.
Any guesses as to why this is fracking up? If any additional info is needed I can post it. I didn't want to upload my entire class for wall-of-code reasons.
Insert
template <typename T>
void AVL<T>::insert(T data)
{
insert(mRootNode, data);
}
template <typename T>
void AVL<T>::insert(Node<T>*& node, const T &data)
{
// If the tree is empty, make a new node and make it
// the root of the tree.
if (node == NULL)
{
node = new Node<T>(data);
return;
}
// If num is already in tree: return.
if (node->mData == data)
return;
// The tree is not empty: insert the new node into the
// left or right subtree.
if (data < node->mData)
{
insert(node->mLeft, data);
}
else
{
insert(node->mRight, data);
}
// Check for balance errors
int balance = getBalance(node);
bool
rotL = (balance > 1) && (getBalance(node->mRight) == 1),
rotR = (balance < -1) && (getBalance(node->mLeft) == -1),
rotRL = (balance > 1) && (getBalance(node->mRight) == -1),
rotLR = (balance < -1) && (getBalance(node->mLeft) == 1);
if (rotR)
{
rotateRight(node);
}
}
Right Rotation
template <class T>
void AVL<T>::rotateRight(Node<T>*& node)
{
showTree(); // Show tree before rotation
Node<T>* other = node->mLeft;
Node<T>* tmp = other->mRight;
other->mRight = node;
node->mLeft = tmp;
showTree(); // Show tree after rotation
}
Balance
template <class T>
int AVL<T>::getBalance(Node<T>* node)
{
return (node->mRight ? treeHeight(node->mRight) : 0) - (node->mLeft ? treeHeight(node->mLeft) : 0);
}
Stub
void StubAVL()
{
AVL<int> tree;
cout << "Inserting: 5\n";
tree.insert(5);
cout << "Inserting: 8\n";
tree.insert(8);
cout << "Inserting: 3\n";
tree.insert(3);
cout << "Inserting: 12\n";
tree.insert(12);
cout << "Inserting: 9\n";
tree.insert(9);
cout << "Inserting: 2\n";
tree.insert(2);
cout << "Inserting: 13\n";
tree.insert(13);
cout << "Inserting: 0\n";
tree.insert(0);
cout << "Inserting: -1\n";
tree.insert(-1);
cout << "Inorder: ";
tree.showInOrder();
cout << endl;
cout << "Preorder: ";
tree.showPreOrder();
cout << endl;
cout << "Postorder: ";
tree.showPostOrder();
cout << endl;
cout << "Node Count = " << tree.nodesCount() << endl;
cout << "Leaves Count = " << tree.leavesCount() << endl;
cout << "Height = " << tree.getHeight() << endl;
cout << "The tree looks like:\n";
tree.showTree();
cout
<< "\n\n"
<< "Heights\n";
tree.showHeight();
cout
<< "\n\n"
<< "Balances\n";
tree.showBalance();
cout << "\n\n";
system("pause");
}
Output
Right after it inserts 0 ↑ the children of 3 are deleted.

Largest element of list

I need to find the largest element in the list. In the following code unsubscribed items and ordered them. How to find the last element of list? I think that I need add one more function void maksimum(), but I'm having trouble with that.
#include <iostream>
#include <string>
#include <time.h>
#include <conio.h>
#include <cstdlib>
using namespace std;
struct element
{
int number;
element* next;
element();
};
element::element()
{
next = NULL;
}
struct list
{
element* first;
void fill_list(int number);
void segregate();
void show_list();
void maksimum();
list();
};
list::list()
{
first = NULL;
}
void list::fill_list(int number)
{
element *nowy = new element;
nowy->number = number;
if(first == 0)
{
first = nowy;
}
else
{
element* temp = first;
while(temp->next)
{
temp = temp->next;
}
temp->next = nowy;
}
}
void list::show_list()
{
element* temp = first;
if(temp == 0)
{
cout << "List is empty." << endl;
cout << "No smallest element " << endl;
cout << "No largest element" << endl;
}
else
{
while(temp)
{
cout << temp->number << endl;
temp = temp->next;
}
cout << "the smallest element: : " << first->number << endl;
if(first->next == 0)
{
cout << "Largest element = Smallest element :)" << endl;
}
}
}
void list::segregate()
{
element* new_first = NULL;
element* prv;
element* temp;
element* maks;
while(first)
{
maks = first;
prv = NULL;
temp = first;
while(temp->next)
{
if(temp->next->number > maks->number)
{
prv = temp;
maks = temp->next;
}
temp=temp->next;
}
if (prv)
{
prv->next = maks->next;
}
else
{
first = maks->next;
}
maks->next = new_first;
new_first = maks;
}
first = new_first;
}
int main()
{
int n=0;
int number=0;
list* base = new list;
cout << "Size of list: " << endl;
cin >> n;
for(int i = 0; i < n; i++)
{
cout << "No " << i+1 << ": ";
cin >> number;
base->fill_list(number);
}
base->segregate();
base->show_list();
//base->maksimum();
delete(base);
return 0;
}
How can I do that?
ok. you're right, but I thought that my code shows my work. not matter :)
i solved my problem. My function: ^^
void list::show_list()
{
element * temp = first;
if( temp == 0 )
{
cout << "List is empty." << endl;
cout << "No smallest element " << endl;
cout << "No largest element" << endl;
}
else
{
while( temp->next != 0 )
{
temp = temp->next;
}
cout << "The largest element: " << temp->number << endl;
cout << "The smallest element: " << first->number << endl;
}
}

separating a looping algorithm from actions

Suppose we have a singly linked list of integers and we are given the following requirements:
For a given node, menu option 1 should display the data field of the node and any subsequent nodes in the console output.
For a given node, menu option 2 should display the data field of the node and any subsequent nodes in the console output only if data is multiple of 2.
For a given node, menu option 3 should display the data field of the node and any subsequent nodes in the console output only if data is multiple of 3.
A possible solution is as follows:
struct node {
int data;
node *next;
};
void insertBeginning(node **list, int data)
{
node *n = new node;
n->data = data;
n->next = *list;
*list = n;
}
void option1(node *node)
{
if (node != NULL) {
cout << node->data << endl;
option1(node->next);
}
}
void option2(node *node)
{
if (node != NULL) {
if (node->data % 2 == 0)
cout << node->data << endl;
option2(node->next);
}
}
void option3(node *node)
{
if (node != NULL) {
if (node->data % 3 == 0)
cout << node->data << endl;
option3(node->next);
}
}
void main()
{
node *root = new node;
root->data = 5;
root->next = NULL;
insertBeginning(&root, 4);
insertBeginning(&root, 3);
insertBeginning(&root, 2);
insertBeginning(&root, 1);
cout << "OPTION 1" << endl;
option1(root);
cout << endl;
cout << "OPTION 2" << endl;
option2(root);
cout << endl;
cout << "OPTION 3" << endl;
option3(root);
}
But a closer inspection reveals that in each menu option there is an algorithm that loop through nodes, which is the same in all options, and then a specific action. So it might be good to separate the looping algorithm from the action. How would you do it?
In this case the looping algorithm as well as the actions are very simple, so doing a separation would be killer, but in my situation the looping algorithm and the actions are more complex, and I want to avoid copying and pasting the looping algorithm. Also, this case uses a singly linked list, but it could be a tree. Anyway I do not want to distract you with these details.
Finally consider a fourth option:
For a given node, menu option 4 should display the sum of the data field of the node and any subsequent nodes in the console output.
A possible solution is as follows:
void loopNodes(node * n, void action(node * n))
{
if (n != NULL) {
action(n);
loopNodes(n->next, action);
}
}
void option1(node * node)
{
cout << node->data << endl;
}
void option2(node * node)
{
if (node->data % 2 == 0)
cout << node->data << endl;
}
void option3(node * node)
{
if (node->data % 3 == 0)
cout << node->data << endl;
}
int sum;
void option4(node * node)
{
sum += node->data;
}
void main()
{
node *root = new node;
root->data = 5;
root->next = NULL;
insertBeginning(&root, 4);
insertBeginning(&root, 3);
insertBeginning(&root, 2);
insertBeginning(&root, 1);
cout << "OPTION 1" << endl;
loopNodes(root, option1);
cout << endl;
cout << "OPTION 2" << endl;
loopNodes(root, option2);
cout << endl;
cout << "OPTION 3" << endl;
loopNodes(root, option3);
cout << endl;
cout << "OPTION 4" << endl;
sum = 0;
loopNodes(root, option4);
cout << "SUM = " << sum << endl;
}
Option 4 introduced a challenge; the need to maintain state. I used a variable with file scope, but an alternative could be (and this is my final solution):
void loopNodes(node * n, void action(node * n, void *state), void *state)
{
if (n != NULL) {
action(n, state);
loopNodes(n->next, action, state);
}
}
void option1(node * node, void *state)
{
cout << node->data << endl;
}
void option2(node * node, void *state)
{
if (node->data % 2 == 0)
cout << node->data << endl;
}
void option3(node * node, void *state)
{
if (node->data % 3 == 0)
cout << node->data << endl;
}
void option4(node * node, void *state)
{
*(int *) state += node->data;
}
void main()
{
node *root = new node;
root->data = 5;
root->next = NULL;
insertBeginning(&root, 4);
insertBeginning(&root, 3);
insertBeginning(&root, 2);
insertBeginning(&root, 1);
cout << "OPTION 1" << endl;
loopNodes(root, option1, NULL);
cout << endl;
cout << "OPTION 2" << endl;
loopNodes(root, option2, NULL);
cout << endl;
cout << "OPTION 3" << endl;
loopNodes(root, option3, NULL);
cout << endl;
cout << "OPTION 4" << endl;
int *sum = new int;
*sum = 0;
loopNodes(root, option4, sum);
cout << "SUM = " << *sum << endl;
}
What do you think?
Any feedback is really appreciated!
Note: I have to use core language facilities (I cannot use the standard library, boost, etc.).
In terms of OOP, your option mechanism depends on some specific handling bound to each option input, which are in this case positive integers. You may consider having a Handle class which takes two inputs during construction, one is option number (i.e an integer) and second is a lambda function or a function pointer which applies the logic. Your linked list then can have a AssignHandles() method to construct the menu behavior automatically.
You could use a templated version for your loop function. This could be used with functions or function objects, which implement the operator ():
#include <iostream>
int list[] = {1, 2, 3, 4, 5};
template<class Option>
void loop(Option & option) {
for (size_t i = 0; i < sizeof(list)/sizeof(list[0]); ++i) {
option(list[i]);
}
}
void print(int e) {
std::cout << e << std::endl;
}
struct Sum {
int sum = 0;
void operator () (int e) {
sum += e;
}
};
int main(int argc, char** argv) {
loop(print);
Sum s;
loop(s);
std::cout << s.sum << std::endl;
return 0;
}