I'm trying to create a non-recursive insert() function. The only example I have in the book is a recursive one and I'm trying to convert it. Just so you have an idea of what I'm trying to accomplish and why I'll include the instructions.
Write a class for implementing a simple binary search tree capable of storing numbers. The class should have member functions:
void insert(double x)
bool search(double x)
void inorder(vector <double> & v)
The insert function should not use recursion directly or indirectly by calling a recursive function.
There is more, but I think this gives the idea behind what I'm asking about. As of now the function just keep recreating the root node. Here is what I have.
Edit: Adding full code for clarity.
#include "stdafx.h"
#include <iostream>
#include <vector>
class BinaryTree {
private:
struct TreeNode {
double value;
TreeNode *left;
TreeNode *right;
TreeNode(double value1,
TreeNode *left1 = nullptr,
TreeNode *right1 = nullptr) {
value = value1;
left = left1;
right = right1;
}
};
TreeNode *root; //pointer to the root of the tree
bool search(double x, TreeNode *t) {
while (t) {
std::cout << "running through t." << std::endl;
if (t->value == x) {
return true;
}
else if (x < t->value) {
std::cout << "wasn't found, moving left." << std::endl;
search(x, t->left);
}
else {
std::cout << "wasn't found, moving right." << std::endl;
search(x, t->right);
}
}
std::cout << "wasn't found." << std::endl;
return false;
}
public:
std::vector<TreeNode> v;
BinaryTree() {
root = nullptr;
}
void insert(double x) {
TreeNode *tree = root;
if (!tree) {
std::cout << "Creating tree." << x << std::endl;
root = new TreeNode(x);
return;
}
while (tree) {
std::cout << "Adding next value." << std::endl;
if (tree->value == x) return;
if (x < tree->value) {
tree = tree->left;
tree->value = x;
}
else {
tree = tree->right;
tree->value = x;
}
}
}
bool search(double x) {
return search(x, root);
}
/*void inOrder(TreeNode *v) const {
while (root != nullptr) {
inOrder(root->left);
v.push_back(root->value);
inOrder(root->right);
v.push_back(root->value);
}
}*/
};
int main() {
BinaryTree t;
std::cout << "Inserting the numbers 5, 8, 3, 12, and 9." << std::endl;
t.insert(5);
t.insert(8);
t.insert(3);
t.insert(12);
t.insert(9);
std::cout << "Looking for 12 in tree." << std::endl;
if (t.search(12)) {
std::cout << "12 was found." << std::endl;
}
std::cout << "Here are the numbers in order." << std::endl;
return 0;
}
In your insert() method, you're setting the value of every node you pass to the new value. That's probably not what you intended.
If you want to insert it, you need to figure out where it goes, create a new node with the appropriate value, and insert the new node into the tree, being careful to handle the nodes that were there previously.
Related
I tried creating a binary search tree, using youtube and examples from my professor to help, but display in Driver.cpp doesn't show any node of the tree except "null" (which was intended to represent nullptr). I think it's because my "root" remains as nullptr, even though I've inserted a new node. The output should be "23 null null". Sorry if the codes aren't short and optimized, I want to make things clear for myself when I reread them later.
P.S.: I've deleted some unfinished functions in the code posted here so there might be minor mistakes
//Driver.cpp
#include <iostream>
#include "Overall Tree.h";
using namespace std;
int main()
{
BinaryTree tree_1;
tree_1.insertNode(23);
tree_1.display();
return 0;
}
//Overall Tree.h
#include <iostream>
using namespace std;
class BinaryTree
{
struct Node
{
int data;
Node* left;
Node* right;
};
private:
Node* root;
public:
// Constructors and Destructors
BinaryTree();
//traversal functions
void preOrder();
void inOrder();
void postOrder();
void preOrderTraverse(Node*);
void inOrderTraverse(Node*);
void postOrderTraverse(Node*);
//display function
void display();
//insert functions
void insertNode(int);
void insert(Node*, Node*);
};
BinaryTree::BinaryTree()
{
root = nullptr;
}
//display traversals
void BinaryTree::display()
{
cout << "Pre-order traversal: " << endl;
preOrder();
cout << endl << endl;
cout << "In-order traversal: " << endl;
inOrder();
cout << endl << endl;
cout << "Post-order traversal: " << endl;
postOrder();
}
// traversals
void BinaryTree::preOrder()
{
preOrderTraverse(root);
}
void BinaryTree::inOrder()
{
inOrderTraverse(root);
}
void BinaryTree::postOrder()
{
postOrderTraverse(root);
}
void BinaryTree::preOrderTraverse(Node* root)
{
if (root != nullptr)
{
cout << root->data << " ";
preOrderTraverse(root->left);
preOrderTraverse(root->right);
}
else
cout << "null ";
}
void BinaryTree::inOrderTraverse(Node* root)
{
if (root != nullptr)
{
preOrderTraverse(root->left);
cout << root->data << " ";
preOrderTraverse(root->right);
}
else
cout << "null ";
}
void BinaryTree::postOrderTraverse(Node* root)
{
if (root != nullptr)
{
preOrderTraverse(root->left);
preOrderTraverse(root->right);
cout << root->data << " ";
}
else
cout << "null ";
}
//insert
void BinaryTree::insertNode(int x)
{
Node* newNode = new Node;
newNode->data = x;
newNode->left = nullptr;
newNode->right = nullptr;
insert(newNode, this->root);
}
void BinaryTree::insert(Node* newNode, Node* p)
{
if (p == nullptr)
p = newNode;
else
if (newNode->data < p->data)
insert(newNode, p->left);
else if (newNode->data > p->data)
insert(newNode, p->right);
else
cout << "Value already existed in the tree.";
}
You should pass pointer to pointer to root in your insert function like:
void BinaryTree::insert(Node* newNode, Node** p)
{
if (*p == nullptr) {
*p = newNode;
} else {
if (newNode->data < (*p)->data) {
insert(newNode, &(*p)->left);
} else if (newNode->data > (*p)->data) {
insert(newNode, &(*p)->right);
} else {
cout << "Value already existed in the tree.";
}
}
}
and then use this function like:
insert(newNode, &this->root);
Why pointer to pointer?
Because you want modifications of the parameter (in this case p parameter), made in the insert function, to affect the argument which the caller passed in.
EDIT
You can also use reference for this purpose:
void BinaryTree::insert(Node* newNode, Node*& p)
{
if (p == nullptr) {
p = newNode;
} else {
if (newNode->data < p->data) {
insert(newNode, p->left);
} else if (newNode->data > p->data) {
insert(newNode, p->right);
} else {
cout << "Value already existed in the tree.";
}
}
}
and then use it like:
insert(newNode, this->root);
I would suggest using reference because of the cleaner syntax IMO.
BST.cpp's overloaded move assignment operator:
BST& BST::operator=(BST&& otherBST) {
if (this != &otherBST) {
if (root) {
stack <Node*> nodeStack;
nodeStack.push(root);
Node *currentNode = nullptr;
while (!nodeStack.empty()) {
currentNode = nodeStack.top();
nodeStack.pop();
if (currentNode->rlink) {
nodeStack.push(currentNode->rlink);
}
if (currentNode->llink) {
nodeStack.push(currentNode->llink);
}
delete currentNode;
currentNode = nullptr;
}
cout << root << endl; // This is where it seems like root is not being deleted correctly/nullptr'd.
}
root = move(otherBST.root);
otherBST.root = nullptr;
}
else {
cerr << "ERROR: Cannot assign to self." << endl;
}
return *this;
}
Look at the cout << root << endl part that I commented on. When that piece of code is ran it prints out an address other than 00000000. It doesn't seem like they're being deleted correctly.
This is a code where the calling object's BST is deleted (all branches) and then it steals otherBST's tree. Move assignment operator. But why is it not printing a nullptr and instead printing another address? It doesn't seem like it's being deleted correctly.
Here's for reference:
This is the screenshot of test driver being ran: click here to see.
Main.cpp
#include <iostream>
#include "Test.h"
using namespace std;
int main()
{
runTest();
cout << endl << endl;
system("Pause");
return 0;
}
Test.h
#include "BST.h"
void runTest() {
cout << "--------------------------------------------------------------------" << endl;
cout << "Binary Search Tree Test Driver" << endl;
cout << "--------------------------------------------------------------------" << endl;
// Initialization:
BST bst1;
// Traversal when there are no elements in the tree:
cout << "BST traversal when there are no elements within the tree (bst1): " << endl;
bst1.preorderTraversal();
cout << endl;
cout << "BST, inserting one element into the tree recursively and non-recursively (bst1): " << endl;
bst1.insert(21);
bst1.preorderTraversal();
cout << endl;
bst1.insert(69);
bst1.preorderTraversal();
cout << endl;
cout << "BST, inserting duplicate elements into the tree recursively (bst1): " << endl;
bst1.insert(32);
bst1.insert(32);
bst1.preorderTraversal();
cout << endl;
cout << "BST using the function destroyTree (bst1): " << endl;
bst1.destroyTree();
bst1.preorderTraversal();
cout << endl;
cout << "BST copy constructor by copy constructing bst1 (bst2): " << endl;
bst1.insert(21);
bst1.insert(69);
BST bst2(bst1);
bst2.preorderTraversal();
cout << endl;
cout << "BST move constructor by move constructing bst1 (bst3): " << endl;
BST bst3 = move(bst1);
bst3.preorderTraversal();
cout << endl;
cout << "BST move assignment operator by move assigning bst2 (bst1) when bst1 has no elements in its tree: " << endl;
bst1.destroyTree();
bst1 = move(bst2);
bst1.preorderTraversal();
cout << endl;
bst1.destroyTree();
bst2.destroyTree();
cout << "BST move assignment operator by move assigning bst2 (bst1) when bst1 already has some elements in its tree: " << endl;
bst1.insert(21);
bst1.insert(105);
bst1.insert(18);
bst1.insert(16);
bst1.insert(7);
bst1.insert(19);
bst1.insert(109);
bst1.insert(125);
bst1.insert(101);
bst2.insert(691);
bst1 = move(bst2);
bst1.preorderTraversal();
cout << endl;
}
BST.h
#ifndef BST_H
#define BST_H
#include <string>
#include <iostream>
#include <stack>
using namespace std;
class Node
{
friend class BST;
public:
Node() : data(0), rlink(nullptr), llink(nullptr) {}
~Node() {}
private:
int data;
Node *rlink, *llink;
};
class BST
{
public:
BST();
BST(const BST& otherBST);
BST(BST&& otherBST);
void insert(int item);
void insertNonRecursive(int item);
void preorderTraversal() const;
// BST& operator=(const BST& otherBST);
BST& operator=(BST&& otherBST);
void destroyTree();
~BST();
private:
Node * root; // Pointer to the root.
void copyConstructor(const Node *p);
void insert(Node* &p, Node *newNode);
void preorderTraversal(const Node *p) const;
void destroyTree(Node *&p);
};
#endif
BST.cpp
#include "BST.h"
BST::BST() : root(nullptr) {}
BST::BST(const BST& otherBST) {
copyConstructor(otherBST.root);
}
BST::BST(BST&& otherBST) {
root = move(otherBST.root);
otherBST.root = nullptr;
}
void BST::copyConstructor(const Node *p) {
if (p != nullptr) {
insert(p->data);
copyConstructor(p->llink);
copyConstructor(p->rlink);
}
}
void BST::insert(int insertItem)
{
Node *newNode = new Node;
newNode->data = insertItem;
insert(root, newNode);
}
void BST::insert(Node* &p, Node *newNode)
{
if (p == nullptr)
p = newNode;
else if (p->data > newNode->data)
insert(p->llink, newNode);
else
insert(p->rlink, newNode);
}
void BST::insertNonRecursive(int item) {
if (root == nullptr) {
root = new Node();
root->data = item;
}
else {
Node *current = root;
bool searching = true;
while (searching) {
if (item > current->data && current->rlink != nullptr) {
current = current->rlink;
}
else if (item < current->data && current->llink != nullptr) {
current = current->llink;
}
else if (item == current->data) {
cerr << "The item to insert is already in the list, duplicates are not allowed." << endl;
searching = false;
}
else {
if (item > current->data) {
current->rlink = new Node();
current->rlink->data = item;
}
else {
current->llink = new Node();
current->llink->data = item;
}
searching = false;
}
}
}
}
void BST::preorderTraversal() const {
if (root == nullptr)
cerr << "There is no tree.";
else
{
preorderTraversal(root);
}
}
void BST::preorderTraversal(const Node *p) const {
if (p != nullptr) {
cout << p->data << " ";
preorderTraversal(p->llink);
preorderTraversal(p->rlink);
}
}
BST& BST::operator=(BST&& otherBST) {
if (this != &otherBST) {
if (root) {
stack <Node*> nodeStack;
nodeStack.push(root);
Node *currentNode = nullptr;
while (!nodeStack.empty()) {
currentNode = nodeStack.top();
nodeStack.pop();
if (currentNode->rlink) {
nodeStack.push(currentNode->rlink);
}
if (currentNode->llink) {
nodeStack.push(currentNode->llink);
}
delete currentNode;
currentNode = nullptr;
}
cout << root << endl; // This is where it seems like root is not being deleted correctly/nullptr'd.
}
root = move(otherBST.root);
otherBST.root = nullptr;
}
else {
cerr << "ERROR: Cannot assign to self." << endl;
}
return *this;
}
void BST::destroyTree(Node* &p)
{
if (p != nullptr)
{
destroyTree(p->llink);
destroyTree(p->rlink);
delete p;
p = nullptr;
}
}
void BST::destroyTree()
{
destroyTree(root);
}
BST::~BST()
{
destroyTree(root);
}
I think the line you mentioned is just fine and is not leaking anything. It is just that the pointer isn't assigned to NULL.
You are probably doing expecting pA tobe NULL in below example
int *pA = new int;
int *pB = pA;
delete pB;
pB=NULL;
printf("pA=0x%p, pB=0x%p", pA,pAB);
Note that even though pA points to something,which is a dangling pointer now, there is no leak.
To get desired behavior, you can set the root to NULL after you are done pushing in stack.
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 :)
I am able to print my expression tree in inorder. But I need to be able to print it in inorder with parenthesis. for example postorder 53+ should output (5+3)
I currently have:
void printTree(struct TreeNode *tree)
{
if (tree != NULL)
{
if (isalpha(tree->info) || isdigit(tree->info))
cout << "(";
printTree( tree->left);
cout<< tree->info;
printTree(tree->right);
if (isalpha(tree->info) || isdigit(tree->info))
cout << ")";
}
}
But this gives me incorrect output. If i enter postfix expression 62/5+ it gives me (6)/(2)+(5)
:(
You need to distinguish between leaf nodes and non-leaf nodes. Only non-leaf nodes are enclosed in parantheses.
bool isLeaf(struct TreeNode* tree) {
return tree->left == 0 && tree->right == 0;
}
void printTree(struct TreeNode* tree) {
if (tree != NULL) { // this test could be omitted if the printed tree is not empty
if (isLeaf(tree)) {
cout << tree->info;
}
else {
cout << "(";
printTree(tree->left);
cout << tree->info;
printTree(tree->right);
cout << ")";
}
}
}
Try reversing the if conditions that decide whether the parentheses should be printed :
void printTree(struct TreeNode *tree)
{
if (tree != NULL)
{
if (!(isalpha(tree->info) || isdigit(tree->info)))
cout << "(";
printTree( tree->left);
cout<< tree->info;
printTree(tree->right);
if (!(isalpha(tree->info) || isdigit(tree->info)))
cout << ")";
}
}
Or probably even better :
void printTree(struct TreeNode *tree)
{
if (tree != NULL)
{
if (isoperator(tree->info))
cout << "(";
printTree( tree->left);
cout<< tree->info;
printTree(tree->right);
if (isoperator(tree->info))
cout << ")";
}
}
where isoperator is appropriately defined to distinguish operators from operands.
So I am unsure of how to make this insert_after method. Yes, this is a hw assignment but I have been looking at this trying to figure how to implement this for hours. Also, I can't get my error checking to work correctly as it will completely abort the program.
Help a C++ noob out?
#include <iostream>
#include <cassert>
#include <stdexcept>
using namespace std;
template<class T> class mylist;
template<class T>
ostream& operator<<(ostream& out, const mylist<T>&l);
template <typename T>
class mylist {
public:
struct node {
T data;
node* next_ptr;
node(const T&d, node* n):data(d),next_ptr(n){}
};
node* head_ptr;
friend ostream& operator<< <>(ostream& out, const mylist<T>&l);
class iterator {
node* ptr;
public:
iterator(node*p):ptr(p){}
iterator next(){return ptr->next_ptr;}
T& operator*(){return ptr->data;}
bool operator!=(const iterator& other){return ptr!=other.ptr;}
iterator operator++(){ptr=ptr->next_ptr; return *this;}
};
public:
mylist():head_ptr(0) {}
iterator begin(){return iterator(head_ptr);}
iterator end(){return iterator(0);}
// returns a reference to the data in the ith node in the list
// raise an out_of_bounds exception if not enough elements
//****can't get error check to work here****/
T& at(unsigned i)
{
try{
cout << endl;
unsigned j = 0;
//node* node_pointer;
iterator iter = begin();
while(j < i && iter.next() != NULL)
{
++iter;
j++;
/*if(!(iter.next() != NULL))
{ throw out_of_range("out of bounds");
}*/
}
cout << "leaving now" << endl;
return *iter;}
catch(out_of_range& oor){cerr << "out of range" << oor.what() << endl;}
}
// same as at
//****can't get error check to work here****/
T& operator[](unsigned i)
{
try{
cout << endl;
unsigned j = 0;
//node* node_pointer;
iterator iter = begin();
while(j < i && iter.next() != NULL)
{
++iter;
j++;
/*if(!(iter.next() != NULL))
{ throw out_of_range("out of bounds");
}*/
}
cout << "leaving now" << endl;
return *iter;}
catch(out_of_range& oor){cerr << "out of range" << oor.what() << endl;}
}
// insert after the node 'pointed' by place
void insert_after(const T&data, const iterator &place)
{
if(empty())
push_front(data);
}
// removes the first node, returns its data
T pop_front(){
return 0;
}
// removes the node after the node 'pointed' by place
void remove_after(const iterator &place) {
}
// destructor, needs to delete all nodes in the list
~mylist() {
}
// you're done here
// insert at beginning of list
void push_front(const T& data) {
head_ptr=new node(data,head_ptr);
}
bool empty() { return head_ptr==0;}
void push_back(const T&data) {
if(empty())
push_front(data);
node* last_ptr=head_ptr;
while(last_ptr->next_ptr != 0)
last_ptr=last_ptr->next_ptr;
// pointing to last node on the list
last_ptr->next_ptr=new node(data,0);
}
unsigned length() {
unsigned l=0;
node*current_ptr=head_ptr;
while(current_ptr!=0) {
l++;
current_ptr=current_ptr->next_ptr;
}
return l;
}
void print_all(void) {
cout << "mylist{";
for(node*current_ptr=head_ptr;
current_ptr!=0;
current_ptr=current_ptr->next_ptr){
cout << current_ptr->data << " ";
}
cout <<"}";
}
};
template<typename T>
ostream& operator<<(ostream& out, const mylist<T>&l) {
out << "mylist{";
typename mylist<T>::node* current_ptr;
for(current_ptr=l.head_ptr; current_ptr!=0;
current_ptr=current_ptr->next_ptr) {
out << current_ptr -> data << " ";
}
out <<"}";
return out;
}
int main(void)
{
mylist<int>::node h(4,0);
mylist<int> l;
mylist<int> z;
cout << l.length() << endl;
l.push_front(6);
l.push_front(7);
cout << l.length() << endl;
l.push_back(10);
l.print_all();
unsigned int i = 5;
cout << "data at i = "<< i <<" is: " << l.at(i) << endl;
cout << "data at l[" << i <<"] is " << l[i] << endl;
z.insert_after(23,iter);
z.push_front(18);
z.push_front(x.data);
z.print_all();
cout << endl << "goodbye" << endl;
/*for(mylist<int>::iterator curr=l.begin(); curr!=l.end(); ++curr) {
cout << *curr << endl;
}*/
}
Since this is homework I will not give example code, but: you must have a way for mylist to access the node* in your iterator class. The insert_after method can then modify the next_ptr of that node to insert a new node.