二进制堆无匹配函数错误

时间:2013-03-02 00:25:43

标签: c++ templates heap

我正在处理二进制堆的链表类型实现,并且在编写时我遇到了一些错误。现在我的main.cpp是一个简单的测试,用于向堆中添加一个元素,但当我调用我的“添加到堆”函数时,它说它无法找到它。这是代码:

的main.cpp

#include <QtCore/QCoreApplication>
#include "Queue.h"
#include "Heap.h"
#include <bitset>
#include <cmath>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Heap<int> H;
    H.AddToHeap(1);


    return a.exec();
}

Heap.h

#ifndef HEAP_H
#define HEAP_H
#include "Node.h"
#include <iostream>
#include <bitset>
#include <cmath>

enum BOUNDARY_ERRORS{OUT_OF_BOUNDS, INVALID_NODE};

template <typename T>
class Heap
{
public:
    Heap();
    Heap(const Heap &other);
    void operator=(const Heap &other);
    ~Heap();

    void AddToHeap(T &data);
    Heap& operator<<(T &data);
    T& Pop();
    Heap& operator>>(T &destination);
    bool Empty() { return size==0; }
    T Peek();

    template <typename U> friend
    ostream& operator<<(const ostream &out, const Heap<U> &H);

    template <typename U> friend
    istream& operator>>(const istream &in, const Heap<U> &H);

private:
    int size;
    Node<T> *rootptr;
    void AddToVacantNode(T &data);
    Node<T>* FindNode(int n);
    Node<T>* FindParentNode(int n);
    Node<T>* LargestChild(Node<T> *nodeptr);
    Node<T>* SmallestChild(Node<T> *nodeptr);
    void Upheap();
    void Downheap();
    void Switch(Node<T> *a, Node<T> *b);
    void Replace(Node<T> *a, Node<T> *b);
    void Copy(const Heap &other);
    bool MIN;

    void Clear();
};

template <typename T>
Heap<T>::Heap()
{
    size = 0;
    rootptr = NULL;
    MIN = 0;
}

template <typename T>
Heap<T>::Heap(const Heap<T> &other)
    : Heap()
{
    Copy(other);
}

template <typename T>
void Heap<T>::operator=(const Heap<T> &other)
{
    Copy(other);
}

template <typename T>
Heap<T>::~Heap()
{
    Clear();
}

template <typename T>
void Heap<T>::AddToVacantNode(T &data)
{
    if (Empty())
        rootptr = new Node<T>(data);
    else
    {
        int destination = size  + 1;
        Node<T> newnode(data);
        Node<T> *parentptr = FindParentNode(destination);
        if (!destination%2)
            parentptr->AddLeftChild(newnode);
        else
            parentptr->AddRightChild(newnode);
    }
}

template <typename T>
Node<T>* Heap<T>::FindParentNode(int n)
{
    if (n == 1)
        return NULL;
    int parentnumber;
    if (!n%2)
    {
        parentnumber = n / 2;
        Node<T> *nodeptr = FindNode(parentnumber);
        return nodeptr;
    }
    else
    {
        parentnumber = (n - 1) / 2;
        Node<T> *nodeptr = FindNode(parentnumber);
        return nodeptr;
    }
}

template <typename T>
void Heap<T>::Upheap()
{
    Node<T> *parentptr = FindParentNode(size);
    Node<T> *childptr = FindNode(size);
    if (MIN)
    {
        while (parentptr && *childptr < *parentptr)
        {
            switch(parentptr, childptr);
            parentptr = FindParentNode(parentptr);
            childptr = FindParentNode(childptr);
        }
        return;
    }
    else
    {
        while (parentptr && *childptr > *parentptr)
        {
            switch(parentptr, childptr);
            parentptr = FindParentNode(parentptr);
            childptr = FindParentNode(childptr);
        }
        return;
    }

}

template <typename T>
Node<T>* Heap<T>::LargestChild(Node<T> *nodeptr)
{
    if (!nodeptr->LeftChild() && !nodeptr->RightChild())
        return NULL;
    else if (nodeptr->LeftChild() && !nodeptr->RightChild())
        return nodeptr->LeftChild();
    else if (nodeptr->RightChild() && !nodeptr->LeftChild())
        return nodeptr->RightChild();
    else
        return (*(nodeptr->LeftChild() > *(nodeptr->RightChild())))?
                    nodeptr->LeftChild() : nodeptr->RightChild();
}

template <typename T>
Node<T>* Heap<T>::SmallestChild(Node<T> *nodeptr)
{
    if (!nodeptr->LeftChild() && !nodeptr->RightChild())
        return NULL;
    else if (nodeptr->LeftChild() && !nodeptr->RightChild())
        return nodeptr->LeftChild();
    else if (nodeptr->RightChild() && !nodeptr->LeftChild())
        return nodeptr->RightChild();
    else
        return (*(nodeptr->LeftChild() < *(nodeptr->RightChild())))?
                    nodeptr->LeftChild() : nodeptr->RightChild();
}

template <typename T>
void Heap<T>::Downheap()
{
    Node<T> *nodeptr = FindNode(size);
    *rootptr = *nodeptr;




}

template <typename T>
void Heap<T>::Replace(Node<T> *a, Node<T> *b)
{
    a->Data() = b->Data();
    b->NullPtrs();
    Node<T> *parentptr = FindParentNode(b);
    if (parentptr->LeftChild() = b)
    {
        parentptr->NullLeftChild();
        delete b;
        b = NULL;

    }
    else
    {
        parentptr->NullRightChild();
        delete b;
        b = NULL;
    }
    return;
}

template <typename T>
void Heap<T>::AddToHeap(T &data)
{
    AddToVacantNode(data);
    Upheap();
    size++;
}

template <typename T>
Heap<T>& Heap<T>::operator<<(T &data)
{
    AddToHeap(data);
    return *this;
}

template <typename T>
T& Heap<T>::Pop()
{
    return rootptr->Data();
    Downheap();
    size--;
}

template <typename T>
Heap<T>& Heap<T>::operator>>(T &destination)
{
    destination = rootptr->Data();
    Downheap();
    size--;
}

template <typename T>
T Heap<T>::Peek()
{
    if (!Empty())
        return rootptr->Data();
}

template <typename T>
ostream& operator<<(const ostream &out, const Heap<T> &H)
{
    return;
}

template <typename T>
istream& operator>>(const istream &in, const Heap<T> &H)
{
    return;
}

template <typename T>
void Heap<T>::Switch(Node<T> *a, Node<T> *b)
{
    T temp;
    temp = a->Data();
    a->SetData(b->Data());
    b->SetData(temp);
}

template <typename T>
void Heap<T>::Copy(const Heap &other)
{
    if (this != &other && !other.Empty())
    {
        MIN = other.MIN;
        Node<T> *nodeptr;
        Clear();
        for (int n=1; n<=other.size; n++)
        {
            nodeptr = other.FindNode(n);
            AddToHeap(nodeptr->data);
        }
    }
}

template <typename T>
Node<T>* Heap<T>::FindNode(int n)
{
    if (n > size || n < 1)
        throw OUT_OF_BOUNDS;

    int x = floor(log(n)/log(2)+1);
    bitset<20> bs(n);
    Node<T> *nodeptr = rootptr;

    for (int i=x-2; i>=0; i--)
    {
        if (!bs[i])
            nodeptr = nodeptr->LeftChild();
        else
            nodeptr = nodeptr->RightChild();
    }
    return nodeptr;
}

template <typename T>
void Heap<T>::Clear()
{
    for (int n=size; n>0; n++)
    {
        Node<T> *nodeptr = FindNode(n);
        nodeptr->NullPtrs();
        delete nodeptr;
    }
    rootptr->NullPtrs();
    delete rootptr;
}

#endif // HEAP_H

Node.h

#ifndef NODE_H
#define NODE_H
#include <iostream>

template <typename T>
class Node
{
public:
    Node();
    Node(T &DATA);
    Node(const Node<T> &other);
    Node<T>& operator=(const Node<T> &other);
    Node<T>& operator<<(const T &nodedata);
    bool operator==(const Node<T> &other);
    bool operator<(const Node<T> &other);
    bool operator>(const Node<T> &other);
    bool operator<=(const Node<T> &other);
    bool operator>=(const Node<T> &other);
    bool operator!=(const Node<T> &other);
    ~Node();
    T Data() const { return data; }
    void SetData(const T &nodedata);
    void AddLeftChild(const Node<T> *leftchildptr);
    void AddRightChild(const Node<T> *rightchildptr);
    Node<T> *LeftChild() { return leftchild; }
    Node<T> *RightChild() { return rightchild; }
    void NullLeftChild() { leftchild = NULL; }
    void NullRightChild() { rightchild = NULL; }
    void NullPtrs() { leftchild = rightchild = NULL; }

    template <typename U> friend
    ostream& operator<<(ostream &out, Node<U> &node);

private:
    T data;
    Node<T> *leftchild;
    Node<T> *rightchild;
    void Copy(const Node<T> &other);

};

template <typename T>
Node<T>::Node()
{
    NullPtrs();
    return;
}

template <typename T>
Node<T>::Node(T &DATA)
{
    NullPtrs();
    data = DATA;
    return;
}

template <typename T>
Node<T>::Node(const Node<T> &other)
{
    Copy(other);
    return;
}

template <typename T>
Node<T>& Node<T>::operator=(const Node &other)
{
    if (this != &other)
        Copy(other);
    return this;
}

template <typename T>
Node<T>& Node<T>::operator<<(const T &nodedata)
{
    SetData(nodedata);
}

template <typename T>
bool Node<T>::operator==(const Node<T> &other)
{
    return (data == other.data);
}

template <typename T>
bool Node<T>::operator<(const Node<T> &other)
{
    return (data < other.data);
}

template <typename T>
bool Node<T>::operator>(const Node<T> &other)
{
    return (data > other.data);
}

template <typename T>
bool Node<T>::operator<=(const Node<T> &other)
{
    return (data < other.data || data == other.data);
}

template <typename T>
bool Node<T>::operator>=(const Node<T> &other)
{
    return (data > other.data || data == other.data);
}

template <typename T>
bool Node<T>::operator!=(const Node<T> &other)
{
    return (data != other.data);
}


template <typename T>
Node<T>::~Node()
{
    NullPtrs();
}

template <typename T>
void Node<T>::SetData(const T &nodedata)
{
    data = nodedata;
}

template <typename T>
void Node<T>::AddLeftChild(const Node<T> *leftchildptr)
{
    leftchild = leftchildptr;
    return;
}

template <typename T>
void Node<T>::AddRightChild(const Node<T> *rightchildptr)
{
    rightchild = rightchildptr;
    return;
}

template <typename U>
ostream& operator<<(ostream &out, Node<U> &node)
{
    out << node.data;
    return out;
}

template <typename T>
void Node<T>::Copy(const Node &other)
{
    leftchild = other.leftchild;
    rightchild = other.rightchild;
    data = other.data;
}

#endif // NODE_H

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

您将rvalue(常量1)传递给Heap::AddToHeap(T &data),它采用非const引用。更改函数签名,使其成为const引用。您还必须将此传播到Heap<T>::AddToVacantNode(T &data)和任何其他相关功能。

这是关于const-correctness的答案:Sell me on const correctness

答案 1 :(得分:0)

您使用文字1调用AddToHeap但是您的AddToHeap仅通过引用接受整数。您无法通过引用传递文字1。如果你的AddToHeap函数通过const引用接受了参数,那么它将起作用。

void AddToHeap(const T& data);