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.
Related
*Create a simple linked list program to create a class list containing
class node {
void *info;
node *next;
public:
node (void *v) {info = v; next = 0; }
void put_next (node *n) {next = n;}
node *get_next ( ) {return next;}
void *get_info ( ) {return info;}
};
Be able to initially fill the list. Provide functions to insert/append nodes and remove nodes from the linked list. Be able to display the contents of the list.
Write a little driver program with at least 5 values passed in (so that 5 nodes are created) as you insert/append, delete and display data, showing the programs operation.
Output: While displaying the data, make sure you use an informational label–using the terms “insert”, “append”, “remove” and any other term which displays the action. All data that is displayed must be displayed in a way in which the mentor can easily read and understand.*
My code runs but it throws Exception thrown: write access violation. this was nullptr. on Line 20 when I debug it. In the output it also stops at Delete 04 of my list and outputs no further data after line 156. I am not sure how to fix this. I tried to force it to output the new list with another cout statement but that did not work. Any assistance would be appreciated. Entire code below.
#include <iostream>
#include <iomanip>
using namespace std;
class Node
{
void* info;
Node* next;
public:
Node(void* v) { info = v; next = 0; }
void put_next(Node* n)
{
next = n;
}
Node* get_next()
{
return next;
}
void* get_info()
{
return info;
}
};
class List {
Node* head;
public:
List() { head = NULL; };
void PRINT();
void APPEND(void* info);
void DELETE(void* info);
};
void List::PRINT() {
Node* temp = head;
if (temp == NULL)
{
cout << "Enter Values" << endl;
return;
}
if (temp->get_next() == NULL)
{
cout << *(int*)temp->get_info();
cout << " => ";
cout << "Invalid" << endl;
}
else
{
while (temp != NULL)
{
cout << *(int*)temp->get_info();
cout << " --> ";
temp = temp->get_next();
}
cout << "Invalid" << endl;
}
}
void List::APPEND(void* info) {
Node* newNode = new Node(info);
newNode->put_next(NULL);
Node* temp = head;
if (temp != NULL)
{
while (temp->get_next() != NULL)
{
temp = temp->get_next();
}
temp->put_next(newNode);
}
else
{
head = newNode;
}
}
void List::DELETE(void* info) {
Node* temp = head;
if (temp == NULL)
{
cout << "Enter Values" << endl;
return;
}
if (temp->get_next() == NULL)
{
if ((int*)(temp->get_info()) == info)
{
delete temp;
head = NULL;
}
}
else
{
Node* previous = NULL;
while (temp != NULL)
{
if ((int*)(temp->get_info()) == info) break;
previous = temp;
temp = temp->get_next();
}
previous->put_next(temp->get_next());
delete temp;
}
}
int main()
{
List list;
int a = 04;
int b = 11;
int c = 12;
int d = 15;
int e = 29;
int* Node1 = &a;
int* Node2 = &b;
int* Node3 = &c;
int* Node4 = &d;
int* Node5 = &e;
cout << "Append: 04" << endl;
list.APPEND(Node1);
cout << "Append: 11" << endl;
list.APPEND(Node2);
cout << "Append: 12" << endl;
list.APPEND(Node3);
cout << "Append: 15" << endl;
list.APPEND(Node4);
cout << "Append: 29" << endl;
list.APPEND(Node5);
cout << endl << "Print List" << endl;
list.PRINT();
cout << endl << "Delete 04" << endl;
list.DELETE(Node1);
list.PRINT();
cout << "Start New List" << endl;
cout << endl << "Delete 12" << endl;
list.DELETE(Node3);
list.PRINT();
return 0;
}
SOLUTION:
//Node.h
#pragma once
class Node
{
void* info;
Node* next;
public:
Node(void* v) { info = v; next = 0; }
void put_next(Node* n)
{
next = n;
}
Node* get_next()
{
return next;
}
void* get_info()
{
return info;
}
};
//List.h
#pragma once
#include "Node.h"
#include <iomanip>
class List {
Node* head;
public:
List() { head = NULL; };
void PRINT();
void APPEND(void* info);
void DELETE(void* info);
};
//List.cpp
#include <iostream>
#include "List.h"
using namespace std;
void List::PRINT() {
Node* temp = head;
if (temp == NULL)
{
cout << "Enter Values" << endl;
return;
}
if (temp->get_next() == NULL)
{
cout << *(int*)temp->get_info();
cout << " => ";
cout << "Invalid" << endl;
}
else
{
while (temp != NULL)
{
cout << *(int*)temp->get_info();
cout << " --> ";
temp = temp->get_next();
}
cout << "Invalid" << endl;
}
}
void List::APPEND(void* info) {
Node* newNode = new Node(info);
newNode->put_next(NULL);
Node* temp = head;
if (temp != NULL)
{
while (temp->get_next() != NULL)
{
temp = temp->get_next();
}
temp->put_next(newNode);
}
else
{
head = newNode;
}
}
void List::DELETE(void* info) {
Node* temp = head;
if (temp == NULL)
{
cout << "Enter Values" << endl;
return;
}
if (temp->get_next() == NULL)
{
if ((int*)(temp->get_info()) == info)
{
delete temp;
head = NULL;
}
}
else
{
Node* previous = NULL;
while (temp != NULL)
{
if ((int*)(temp->get_info()) == info) {
// if node is head then changing the head
if (temp == head)
head = temp->get_next();
break;
}
previous = temp;
temp = temp->get_next();
}
// skip this operation if node is head
if (temp->get_next() != head)
previous->put_next(temp->get_next());
delete temp;
}
}
//Main.cpp
#include <iostream>
#include "List.h"
using namespace std;
int main()
{
List list;
int a = 04;
int b = 11;
int c = 12;
int d = 15;
int e = 29;
int* Node1 = &a;
int* Node2 = &b;
int* Node3 = &c;
int* Node4 = &d;
int* Node5 = &e;
cout << "Append: 04" << endl;
list.APPEND(Node1);
cout << "Append: 11" << endl;
list.APPEND(Node2);
cout << "Append: 12" << endl;
list.APPEND(Node3);
cout << "Append: 15" << endl;
list.APPEND(Node4);
cout << "Append: 29" << endl;
list.APPEND(Node5);
cout << endl << "Print List" << endl;
list.PRINT();
cout << endl << "Delete 04" << endl;
list.DELETE(Node1);
list.PRINT();
cout << "Start New List" << endl;
cout << endl << "Delete 12" << endl;
list.DELETE(Node3);
list.PRINT();
return 0;
}
So whenever you are deleting first node, you missed to set the head to the next node of head.
Commented at the parts which are modified in the else statement of DELETE function
Code:
else
{
Node* previous = NULL;
while (temp != NULL)
{
if ((int*)(temp->get_info()) == info){
// if node is head then changing the head
if (temp == head)
head = temp->get_next();
break;
}
previous = temp;
temp = temp->get_next();
}
// skip this operation if node is head
if (temp->get_next() != head)
previous->put_next(temp->get_next());
delete temp;
}
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'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.
I'm using a class within a class and I'm getting errors, I think it's a linking problem. I get "undefined reference to 'Node::setlink()', 'Node::getlink()', and etc. It's all the node functions I used in linked_list.cpp that are the problem.
For example, linked_list.cpp:(.text+0x9de): undefined reference to
`Node::getlink()'
Linked_list.cpp
#include "linked_list.hpp"
#include "node.hpp"
#include <iomanip>
#include <iostream>
using namespace std;
//default constructor
Linked_list::Linked_list(void)
{
head = new Node();
tail = new Node();
head->setlink(NULL);
tail->setlink(NULL);
cnt = 0;
}
//constructor
Linked_list::Linked_list(data x)
{
head = new Node();
tail = new Node();
Node *newnode = new Node(x);
head->setlink(newnode);
newnode->setlink(tail);
cnt++;
}
//class function
void Linked_list::insert_node(data x)
{
Node *newNode = new Node(x);
Node *prev = new Node();
Node *curr = new Node();
if (head == NULL)
{
newNode->setlink(tail);
head->setlink(newNode);
}
else if (head != NULL)
{
prev->setlink(head);
curr->setlink(head->getlink());
while(curr->getlink() != NULL || newNode->getupc() <= curr->getupc())
{
prev->setlink(curr);
curr->setlink(curr->getlink());
}
prev->setlink(newNode);
newNode->setlink(curr);
}
cnt++;
}
//Class function
void Linked_list::delete_node(int u)
{
char choice;
data temp;
Node *newNode = new Node();
Node *prev = new Node();
Node *curr = new Node();
if (head == NULL)
{
delete newNode;
delete prev;
delete curr;
}
else if (head != NULL)
{
prev->setlink(head);
curr->setlink(head->getlink());
while (curr->getlink() != NULL || curr->getupc() != u )
{
prev->setlink(curr);
curr->setlink(curr->getlink());
}
temp = curr->get_structure();
cout << temp.UPC << setw(15) << temp.desc << setw(15) << "$" << temp.cost << setw(15) << "Aisle: " << temp.aisle << endl;
prev->setlink(curr->getlink());
cout << "Are you sure you want to delete?\n";
cin >> choice;
if (choice == 'y' || choice == 'Y')
{
delete curr;
cnt--;
}
else
{
choice = 'n';
}
}
}
//Class function
void Linked_list::traverse()
{
data temp;
Node *curr = new Node();
if (head == NULL)
{
delete curr;
cout << "The list is empty!\n";
}
else
{
curr->setlink(head->getlink());
while(curr->getlink() != NULL)
{
temp = curr->get_structure();
cout << temp.UPC << setw(15) << temp.desc << setw(15) << "$" << temp.cost << setw(15) << "Aisle: " << temp.aisle << endl;
}
}
}
void Linked_list::retrieve_node(int u)
{
data temp;
Node *x;
x = new Node();
if (head == NULL)
{
delete x;
}
else if (head != NULL)
{
x->setlink(head->getlink());
while (x->getlink() != NULL || x->getupc() != u)
{
x->setlink(x->getlink());
}
temp = x->get_structure();
cout << temp.UPC << setw(15) << temp.desc << setw(15) << "$" << temp.cost << setw(15) << "Aisle: " << temp.aisle << endl;
}
}
void Linked_list::check_empty()
{
if (head != NULL)
{
cout << "The list is empty.\n";
}
else
{
cout << "The list is not empty.\n";
}
}
linked_list.hpp
#include "node.hpp"
#ifndef linked_list_hpp
#define linked_list_hpp
class Linked_list
{
Node *head;
Node *tail;
int cnt;
public:
//default constructor creates empty linked list
Linked_list(void);
//Constructor that creates first node with values
Linked_list(data x);
//Inserts node at correct spot
void insert_node(data x);
//deletes specific node
void delete_node(int u);
//goes through whole list and prints out
void traverse(void);
//returns specific node
void retrieve_node(int u);
//checks if list is empty
void check_empty();
return_number();
};
#endif
node.hpp
#ifndef node_hpp
#define node_hpp
#include "node.hpp"
#include <string>
using namespace std;
struct data
{
int UPC;
string desc;
int quantity;
double cost;
int aisle;
};
class Node
{
data item;
Node *link;
public:
Node(void);
Node(data x);
void setlink(Node *ptr);
Node* getlink();
int getupc();
data get_structure();
bool compare_item(string i);
double processdata();
};
#endif
node.cpp
#include "node.hpp"
Node::Node(void)
{
link = NULL;
}
Node::Node(data x)
{
item = x;
}
void Node::setlink(Node *ptr)
{
link = ptr;
}
Node* Node::getlink()
{
return link;
}
int Node::getupc()
{
return item.UPC;
}
data Node::get_structure()
{
return item;
}
bool Node::compare_item(string i)
{
if(i==item.desc)
{
return true;
}
else
{
return false;
}
}
double Node::processdata()
{
return item.cost*item.quantity;
}
main function
#include <iostream>
#include "node.cpp"
#include "linked_list.cpp"
using namespace std;
void fromfile(Linked_list &x);
void tofile(Linked_list &x);
int main(void)
{
Linked_list ll;
int x, y;
data a;
do
{
cout << "1.Add a grocery item\n" ;
cout << "2.Delete an item\n";
cout << "3.Retrieve an item\n";
cout << "4.Traverse the list forwards and print out all of the items\n";
cout << "5. Exit the program.\n";
cin >> x;
switch(x)
{
case 1:
cout << "Enter UPC code\n";
cin >> a.UPC;
cout << "Enter description(name of item)\n";
cin >> a.desc;
cout << "Enter quantity\n";
cin >> a.quantity;
cout << "Enter cost\n";
cin >> a.cost;
cout << "Enter aisle\n";
cin >>a.aisle;
ll.insert_node(a);
case 2:
cout << "Enter UPC of item you'd like to delete.\n";
cin >> y;
ll.delete_node(y);
case 3:
cout << "Enter UPC code.\n";
cin >> y;
ll.retrieve_node(y);
case 4:
ll.traverse();
case 5:
cout << "Bye!\n";
default:
cout << "Wrong choice, try again!\n";
}
}while (x != 5);
return 0;
}
Please help me out, this is due in 2 hours. I think I got it running somehow for a while and after the code performs in main, it just stop creating output after it reaches a linked_list function. Then, I can't enter anything afterwards.
The only thing not compiling is the linked_list.cpp, and I get a winmain error as well.
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 :)