Reputation: 3025
I wrote a priority queue that utilizes a binary search tree for my data structures class. The out put it produces is correct for some inputs and incorrect for others. Correct output:
Enter number of elements: 5
Enter number 1 of 5: 1
Enter number 2 of 5: 2
Enter number 3 of 5: 3
Enter number 4 of 5: 4
Enter number 5 of 5: 5
Outputting number 1 of 5: 5
Outputting number 2 of 5: 4
Outputting number 3 of 5: 3
Outputting number 4 of 5: 2
Outputting number 5 of 5: 1
Press any key to continue . . .
Incorrect Output
Enter number of elements: 5
Enter number 1 of 5: -56
Enter number 2 of 5: 4
Enter number 3 of 5: 56
Enter number 4 of 5: 21
Enter number 5 of 5: 32
Outputting number 1 of 5: 56
Outputting number 2 of 5: 4
Outputting number 3 of 5: -56
Outputting number 4 of 5: -56
Outputting number 5 of 5: -56
Press any key to continue . . .
Test.cpp
#include <iostream>
#include "CTree.h"
#include "PriorityQueueBST.h"
using namespace std;
int main()
{
int num, input, output;
cout << "Enter number of elements: ";
cin >> num;
PriorityQueueBST p;
for (int x = 0; x < num; x++)
{
cout << "Enter number " << x + 1
<< " of " << num << ": ";
cin >> input;
p.Enqueue(input);
}
for (int y = 0; y < num; y++)
{
cout << "Outputting number " << y + 1
<< " of " << num << ": ";
if(p.IsEmpty())
{
break; //we are done (this is an error!)
}
output = p.Dequeue();
cout << output << endl;
}
system("pause");
return 0;
//CTree* tr = new CTree();
//
//for (int i = 0; i < 3; i++)
// tr->Add();
//tr->View();
//system("pause");
//return 0;
}
BST Declaration
//#ifndef CTREE_H
//#define CTREE_H
//using namespace std;
struct TreeNode
{
int info;
TreeNode* leftLink;
TreeNode* rightLink;
};
class CTree
{
public:
CTree();
~CTree();
void Add(int);
void View();
bool IsEmpty();
int DeleteLargest(TreeNode*);
TreeNode *tree;
private:
void AddItem( TreeNode*&, TreeNode*);
void DisplayTree(TreeNode*);
void Retrieve(TreeNode*&, TreeNode*,bool&);
void Destroy(TreeNode*&);
};
//#endif
BST Implementation
#include <iostream>
#include <string>
using namespace std;
#include "CTree.h"
CTree::CTree()
{
tree = NULL;
}
CTree::~CTree()
{
Destroy(tree);
}
void CTree::Destroy(TreeNode*& tree)
{
if (tree != NULL)
{
Destroy(tree->leftLink);
Destroy(tree->rightLink);
delete tree;
}
}
bool CTree::IsEmpty()
{
if(tree == NULL)
{
return true;
}
else
{
return false;
}
}
void CTree::Add(int dataToEnter)
{
TreeNode* newPerson = new TreeNode();
/*cout << "Enter the person's name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin.getline(newPerson->name, 20);*/
//cout << "Enter the person's contribution: ";
//cin >> newPerson->info;
/*bool found = false;*/
newPerson->info = dataToEnter;
newPerson->leftLink = NULL;
newPerson->rightLink = NULL;
/*Retrieve(tree, newPerson, found);
if (found)
cout << "info allready entered\n";
else*/
AddItem(tree, newPerson);
}
void CTree::View()
{
if (IsEmpty())
{
cout<<"The list is empy";
}
else
{
DisplayTree(tree);
}
};
void CTree::AddItem( TreeNode*& ptr, TreeNode* newPer )
{
if (ptr == NULL)
{
ptr = newPer;
}
else if ( newPer->info < ptr->info)
AddItem(ptr->leftLink, newPer);
else
AddItem(ptr->rightLink, newPer);
}
void CTree::DisplayTree(TreeNode* ptr)
{
if (ptr == NULL)
return;
DisplayTree(ptr->rightLink);
cout << ptr->info << endl; //cout<<ptr->name<<" "<<"$"<<ptr->info <<endl;
DisplayTree(ptr->leftLink);
}
void CTree::Retrieve(TreeNode*& ptr, TreeNode* newPer, bool& found)
{
{
if (ptr == NULL)
{
found = false; // item is not found.
}
else if ( newPer->info < ptr->info)
{
Retrieve(ptr->leftLink, newPer, found);
}
// Search left subtree.
else if (newPer->info > ptr->info)
{
Retrieve(ptr->rightLink, newPer, found);// Search right subtree.
}
else
{
//newPer.info = ptr->info; // item is found.
found = true;
}
}
}
int CTree::DeleteLargest(TreeNode* tr)
{
int largest = tr->info;
TreeNode* prev = NULL;
while (tr->rightLink != NULL)
{
prev = tr;
tr = tr->rightLink;
largest = tr->info;
}
if (prev != NULL && prev->rightLink != NULL)
{
delete prev->rightLink;
prev->rightLink = NULL;
}
return largest;
}
//
//int CTree::DeleteLargest(TreeNode* tr)
//{
// int largest = 0;
// TreeNode* prev = NULL;
//
//
// while (tr->rightLink != NULL)
// {
// prev = tr;
// tr = tr->rightLink;
// largest = tr->info;
// }
//
// prev->rightLink = NULL;
//
// return largest;
//}
/*
if (tr == NULL)
{
cout << "The tree is empty"<<endl;
}
else if (tr->rightLink == NULL)
{
largest = tr->info;
prev->rightLink = NULL;
}
else
{
prev = tr;
tr = tr->rightLink;
largest = DeleteLargest(tr);
}
*/
PQ Declaration
//#include <iostream>
//using namespace std;
//#include "SortedLinkedList.h"
#ifndef PRIORITYQUEUESLL__H
#define PRIORITYQUEUESLL__H
class PriorityQueueBST
{
public:
PriorityQueueBST();
~PriorityQueueBST();
void Enqueue(int);
int Dequeue();
bool IsEmpty();
private:
CTree* ourTree;
//sslNode* head;
};
#endif
PQ Implementation
#include <iostream>
using namespace std;
#include "CTree.h"
#include "PriorityQueueBST.h"
PriorityQueueBST::PriorityQueueBST()
{
ourTree = new CTree();
//head = NULL;
}
PriorityQueueBST::~PriorityQueueBST()
{
}
void PriorityQueueBST::Enqueue(int dataToEnter)
{
ourTree->Add(dataToEnter);
}
int PriorityQueueBST::Dequeue()
{
//check for empty??
return ourTree->DeleteLargest(ourTree->tree);
}
bool PriorityQueueBST::IsEmpty()
{
return ourTree->IsEmpty();
}
Upvotes: 2
Views: 197
Reputation: 183888
In DeleteLargest
, consider what happens if the tree looks like
4
/ \
/ \
2 7
/ \ /
1 3 5
With
int CTree::DeleteLargest(TreeNode* tr)
{
int largest = tr->info;
TreeNode* prev = NULL;
while (tr->rightLink != NULL)
{
prev = tr;
tr = tr->rightLink;
largest = tr->info;
}
if (prev != NULL && prev->rightLink != NULL)
{
delete prev->rightLink;
prev->rightLink = NULL;
}
return largest;
}
you're finding the 7, but cut the 5 out of the tree, it's lost then. And when the right subtree of the root node has been completely removed, tr->rightLink
is NULL
from the start, so prev
remains NULL
and nothing is deleted.
For the first case, you have to graft tr
's left child to prev
's right before deleting tr
. The second case is a bit more complicated. Since you can't change the containing CTree
without changing the function's signature, you can't delete the root node that is passed in. You have to¹ fake that by copying the value of its left child, relinking the children of that, and deleting the original left child.
¹ Well, of course there are other methods available, but all I can think of involve copying an info
and deleting a different node.
Upvotes: 3