操作LinkedList

时间:2017-11-15 04:55:18

标签: c++ pointers generics data-structures linked-list

所以,我正在尝试使用虚拟节点创建一个LinkedList,但是,当运行每个函数的功能时,我遇到重载括号运算符的错误,假设返回给定的项目index:list [n]虽然我不确定代码可能有什么问题。

我花了几个小时看看为什么我在尝试运行每个功能时遇到错误。对不起,问题是如此模糊,但我觉得好像我遗失了一些东西,或者某些东西编码不好,我似乎无法察觉。

这是代码。

#ifndef _LINKED_LIST_GUARD
    #define _LINKED_LIST_GUARD 1

    #include <iostream>
    #include <string>

    #include "ListInterface.h"

    template <typename T>
    class LinkedList : public ListInterface<T>
    {
    private:
        // Created in order to keep track of list size
        int count = 0;

    public:



        // Default contructor
        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 value that the head points to, sinze _head is a dummy node.
        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;

            //Sets the node next to this node to be equal to what the head was previously pointing to. 
            current->_next = _head->_next;

            //Finally, sets the user created node to be the first node within the list, then adds to the count.
            _head->_next = current;

            count++;


        }


        T& operator[](unsigned n)
        {
            //Starts at position one, since this would never return zero.
            int position = 1;

            //If the user input value is greater than the amount of items in the list
            if (n > count)
            {
                //Throws a string exception.
                throw std::string("Invalid Positon");
            }

            //Loops through the LinkedList
            for (Node* current = _head->_next; current != _tail; current = current->_next)
            {
                //If the node at the current position is equal to the user input value
                if (position == n)
                {
                    //returns the current positions data, since it would be the data at user input position
                    return current->_data;
                }
                // If not, adds to position, and checks again.
                position++;
            }
            return _head->_data;
        }


        //uses the pop function over and over until the list is empty, leaving only the _head and _tail dummy nodes.
        void clear()
        {
            do
            {
                pop();
            } while (count != 0);

        }

        bool contains(const T& target) const
        {
            //Loops through the LinkedList.
            for (Node* current = _head->_next; current != _tail; current = current->_next)
            {
                //While looping, if the current node's data is equal to the user input target data, returns true.
                if (current->_data == target)
                    return true;
            }
            // If it never finds anything, returns false.
            return false;
        }

        bool pop()
        {
            //The head would only point to the tail if the list were empty.
            if (_head->_next == _tail)
            {
                std::cout << "Unable to pop, list is empty ";
                return false;
            }


            if (_head->_next != _tail)
            {
                //Creates a new node that has its values equal to the first node within the list.
                Node* deleteNode = _head->_next;
                //Sets the front of the node to be equal to the first node after the heads next node.
                _head->_next = _head->_next->_next;

                //Finally, deletes the node that deleteNode points to, and reduces the count
                delete deleteNode;
                count--;
                return true;
            }
            //If the pop is unsucessful, returns false.
            return false;
        }

        T& last() const
        {
            // There can't be a last value if the list is empty, so throws an exception
            if (_head->_next == _tail)
            {
                //throw std::string("List is empty.");
                std::cout << "List is empty";
            }

            if (_head->_next != _tail)
            {
                for (Node* current = _head->_next; current != _tail; current = current->_next)
                {
                    //Loops through the list until the node that points to tail is located, then returns it. 
                    if (current->_next == _tail)
                        return current->_data;
                }
            }
            return _tail->_data;
        }


        int search(const T& target = T{}) const
        {
            //Once again, starts a position 1, since 0 is not a valid position
            int position = 1;
            //Loops through list
            for (Node* current = _head->_next; current != _tail; current = current->_next)
            {
                //While looping, if the current node's data is equal to the user input target, returns the position
                if (current->_data == target)
                {
                    return position;
                }
                //Otherwise increases the position, and loops again. 
                position++;
            }
            // If it is unable to find the target in the list, returns -1.
            return -1;

        }

        bool isEmpty() const
        {
            // If the _head points to the tail, that means there are no nodes in between, meaning it is empty. 
            if (_head->_next == _tail)
            {
                return true;
            }
            //Otherwise, return false.
            return false;
        }

        unsigned size() const
        {
            //Returns the count, which is altered by remove, pop, and push. 
            return count;
        }


        bool remove(const T& target)
        {
            //Creates a node, whose data is initially null.
            Node* deleteNode = nullptr;
            //Creates another node to follow behind it.
            Node* trailer = _head;
            //Finally, creates a node that is to represent the current node that is being pointed at.
            Node* current = _head->_next;

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

            //If the data is current is equal to the target
            if (current->_data == target)
            {
                // Sets the node to be deleted to current
                deleteNode = current;
                //then, sets current to the node right after.
                current = current->_next;
                //Finally, sets the trailer to the current node, since it's no longer needed
                trailer->_next = current;

                //Then, simply delets the node, and subtracts from the count.
                delete deleteNode;
                count--;
                return true;
            }
            else
                // If it is unable to find the targeted value, returns false.
                std::cout << "unable to remove, item not in list" << std::endl;
            return false;
        }


        //
        // 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

有关修复的总体建议吗?

0 个答案:

没有答案