使用LinkedList

时间:2017-11-14 08:12:16

标签: c++ data-structures linked-list queue nodes

所以,我试图使用我之前创建的LinkedList来实现此Queue。我已经为这两个类提供了代码。目前,我正努力尝试弹出并推动工作而不更改函数原型(它用于作业)。

当专门看peek时(我还没有完成pop),出于某种原因,当我运行代码时,我得到奇怪的指针错误。

错误C2440'默认参数':无法转换为' int'到' int&'

我不确定在这种情况下究竟意味着什么。该函数假设查看队列顶部的对象而不删除它,并根据操作是否成功返回true或false。

以下是QUEUE的信息。

  #ifndef _QUEUE_H
#define _QUEUE_H 1

#include "QueueInterface.h"
#include "LinkedList.hpp"

template <typename T>
class Queue : public QueueInterface<T>
{
protected:
    LinkedList<T> _list;
    int count;

public:

    unsigned size() const
    {
        return count;
    }

    bool push(const T& val = T{})
    {
        _list.push(val);
        count++;
        return true;
    }

    bool empty() const
    {
        return _list.isEmpty();
    }

    bool pop(T& val = T{})
    {
        return true;
    }

    bool peek(T& val = T{}) const
    {
        std::cout << _list.last() << std::endl;
        return true;

    }

    void clear()
    {
        _list.clear();
    }

    int search(const T& target = T{}) const
    {
        return _list.search(target);
    }
    //
    // Internal consistency check
    //

    void toString()
    {
        _list.toString();
    }

public:
    virtual bool check() const
    {
        return _list.check();
    }
};

#endif

这是链接列表。

#ifndef _LINKED_LIST_GUARD
#define _LINKED_LIST_GUARD 1

#include <iostream>

#include "ListInterface.h"

template <typename T>
class LinkedList : public ListInterface<T>
{
public:

    int count = 0;


    LinkedList()
    {
        _head = new Node;
        _tail = new Node;

        _head->_next = _tail;
    }


private:

    //
    // Private node class to facilitate linked list
    //
    class Node
    {
    public:
        T _data;
        Node* _next;

        // Constructor: default
        Node(T d = T{}, Node* n = nullptr) : _data(d), _next(n) {}

        ~Node() { _next = nullptr; }
    };

    //
    // Prevent copying and assigning
    //
    LinkedList(const LinkedList& rhs) {}
    const LinkedList& operator=(const LinkedList& rhs) {}

public:
    //
    // LinkedList instance variables; we use dummy head and tail nodes in this implementation

    unsigned _size;
    Node* _head;
    Node* _tail;

    // Returns the first element in the list
    T& first() const
    {
        return _head->_next->_data;
    }

    // Adds an item to the LEFT side of the linked list
    void push(const T& x)
    {
        // Creates a new node with the user input data.
            Node* current = new Node;
            current->_data = x;

            current->_next = _head->_next;
            _head->_next = current;

            count++;


    }

    // ASK ABOUT
    T& operator[](unsigned n)
    {
        int position = 1;

        if (n != count)
        {
            throw("Invalid Position");
        }

        for (Node* current = _head->_next; current != _tail; current = current->_next, position++)
        {
            if (position == n)
            {
                return current -> _data;
            }
        }


    }


    void clear()
    {
        do
        {
            pop();
        } while (count != 0);

    }

    bool contains(const T& target) const
    {
        for (Node* current = _head->_next; current != _tail; current = current->_next)
        {
            if (current->_data == target)
                return true;
        }
        return false;
    }

    bool pop()
    {
        if (_head->_next == _tail)
        {
            std::cout << "unable to pop, list is empty";
            return false;
        }

        if (_head->_next != _tail)
        {
            Node* deleteNode = _head->_next;
            _head->_next = _head->_next->_next;
            delete deleteNode;
            count--;
            return true;
        }
        return false;
    }

    T& last() const
    {
        if (_head->_next == _tail)
        {
            std::cout << "LIST IS EMPTY" << std::endl;
        }

        if (_head->_next != _tail)
        {
            for (Node* current = _head->_next; current != _tail; current = current->_next)
            {
                if (current->_next == _tail)
                    return current->_data;
            }
        }
    }

    // ASK ABOUT
    int search(const T& target = T{}) const
    {
        int position = 1;
        for (Node* current = _head->_next; current != _tail; current = current->_next)
        {
            if (current->_data == target)
            {
                return position;
            }
            else  position++;
        }
        return -1;

    }

    bool isEmpty() const
    {
        if (_head->_next == _tail)
        {
            return true;
        }
        return false;
    }

    unsigned size() const 
    {

        return count;
    }


    bool remove(const T& target)
    {
        Node* deleteNode = nullptr;
        Node* trailer = _head;
        Node* current = _head->_next;

        while (current != _tail && current-> _data != target)
        {
            trailer = current;
            current = current->_next; 
        }

        if (current->_data == target)
        {
            deleteNode = current;
            current = current->_next;
            trailer->_next = current;

            delete deleteNode;
            count--;
            return true;
        }
        else
            std::cout << "unable to remove, item not in list" << std::endl;
        return false;

    }

    //FOR TESTING
    void toString()
    {
        for (Node* current = _head->_next; current != _tail; current = current->_next)
        {
            std::cout << current->_data << std::endl;
        }
    }

    //
    // Internal consistency check
    //
public:
    virtual bool check() const
    {
        bool sizeConsistent = isSizeConsistent();
        bool headTailConsistent = isEndConsistent();

        if (!sizeConsistent) std::cerr << "Size inconsistent" << std::endl;
        if (!headTailConsistent) std::cerr << "Head / Tail inconsistent" << std::endl;

        return sizeConsistent && headTailConsistent;
    }

    //
    // Stated size is accurate to the entire list
    //
    bool isSizeConsistent() const
    {
        int count = 0;
        for (Node* current = _head->_next; current != _tail; current = current->_next)
        {
            count++;
        }

        return size() == count;
    }

    //
    // Checks that the head and tail are defaulted properly and the
    // respective next pointers are appropriate.
    //
    bool isEndConsistent() const
    {
        if (_head->_data != T{}) return false;

        if (_tail->_data != T{}) return false;

        if (_head->_next == nullptr) return false;

        if (_tail->_next != nullptr) return false;

        if (isEmpty() && _head->_next != _tail) return false;

        if (!isEmpty() && _head->_next == _tail) return false;

        return true;
    }
};

#endif

最后,这是我的主要内容。顶部是测试LinkedList的功能。底部是我正在使用的测试队列。

#include "Queue.hpp"
#include "LinkedList.hpp"
#include <string>
#include <iostream>


int main()
{
    LinkedList<int> list;
    LinkedList<int> listEmpty;
    Queue<int> list2;

    list.push(1);
    list.push(2);
    list.push(3);
    list.push(4);
    list.push(5);



    list.remove(1);

    std::cout << "List contains 4? " << list.contains(4) << std::endl;
    std::cout << "List empty? " << list.isEmpty() << std::endl;
    std::cout << "List size: " << list.size() << std::endl;
    std::cout << "Last in list? " << list.last() << std::endl;
    std::cout << "What is in position 4? " << list[4] << std::endl;
    std::cout << "Search " << list.search(10) << std::endl;
    //std::cout << "3 is in position " << list.search() << std::endl;
    std::cout << " " << std::endl;




    list.toString();
    list.clear();
    std::cout << "///////////////////////////////////////////////////////////////////////////////" << std::endl;
    list.push(4);

    list.toString();
    std::cout << "///////////////////////////////////////////////////////////////////////////////" << std::endl;
    std::cout << "QUEUE STUFF" << std::endl;
    std::cout << "///////////////////////////////////////////////////////////////////////////////" << std::endl;

    list2.push(1);
    list2.push(2);
    list2.push(6);
    list2.push(3);
    list2.push(4);
    list2.push(5);

    std::cout << "Queue empty? " << list2.empty() << std::endl;
    std::cout << "Queue size: " << list2.size() << std::endl;

    std::cout << "First in Queue? " << list2.peek() << std::endl;
    std::cout << "What position is 6 in? : " << list2.search(6) << std::endl;

    list2.toString();



    std::cout << " " << std::endl;

    system("pause");

我想我的问题是,我可以采取哪些措施来修复这个特定的功能?

提前致谢!

1 个答案:

答案 0 :(得分:0)

您的代码存在的问题是peek,如您所说,不应该修改Queue并且不接受任何参数,因为它只是查看结构的顶部并返回{{1 }或true

所以解决方案是删除峰值中的参数,如下所示,所有内容都编译并运行。

false

具体来说,您得到的错误是因为您无法将非恒定左值引用分配为右值引用。 这正是您在bool peek() const { std::cout << _list.last() << std::endl; return true; } 中所做的。 T& val = T{}是一个右值,显然T{}是对val的非const引用。

你可以尝试使用T并自己看一切都很好。