Zzz
Zzz

Reputation: 3025

Priority Queue that Utilizes BST - Funny Ouptut

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

Answers (1)

Daniel Fischer
Daniel Fischer

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

Related Questions