循环链接列表C ++崩溃

时间:2019-01-24 01:53:24

标签: c++

我的指示是: 考虑一个ADT循环列表,它类似于ADT列表,但是将其第一个条目视为紧接在其后。 它的最后一个条目。例如,如果一个循环列表包含六个项目,则实际上检索或删除了第八个项目 涉及列表的第二项。让我们插入到循环列表中,但是其行为与插入到 清单。将ADT循环列表定义并实现为LinkedList的派生类。

但是当我运行代码时,它会打印前五个名称,然后程序崩溃。我该怎么办才能解决这个问题?

这是代码:

CircularList.h

#pragma once
#ifndef _CIRCULAR_LIST
#define _CIRCULAR_LIST
#include "LinkedList.h"
#include "Node.h"
#include "PrecondViolatedExcep.h"

template<class ItemType>
class CircularList :public LinkedList<ItemType>
{
private:
    ListInterface<ItemType>* listPtr;
    int size; 

public:
    CircularList(int s);
    virtual ~CircularList();
    bool remove(int position);
    bool insert(int newPosition, const ItemType& newEntry);
    int getLength();
    void displayList();
    ItemType getEntry(int position) const throw(PrecondViolatedExcep);
};


template <class ItemType>
CircularList<ItemType>::CircularList(int s)
{
    listPtr = new LinkedList<ItemType>();
    size = s;
}

template <class ItemType>
CircularList<ItemType>::~CircularList()
{

}

template<class ItemType>
bool CircularList<ItemType>::insert(int Position, const ItemType& newEntry)
{
    int newPosition = (Position%size);
    if (newPosition == 0)
    {
        newPosition = size;
    }

    listPtr->insert(newPosition, newEntry);
    return true;
}

template<class ItemType>
int CircularList<ItemType>::getLength()
{
    return size;
}

template<class ItemType>
bool CircularList<ItemType>::remove(int position)
{
    int newPosition = (position%size);
    if (newPosition == 0)
        newPosition = size;
    return listPtr->remove(newPosition);
}

template<class ItemType>
ItemType CircularList<ItemType>::getEntry(int position) const throw(PrecondViolatedExcep)
{
    int newPosition = (position%size);
    if (newPosition = 0)
        newPosition = size;
    return listPtr->getEntry(newPosition);
}


template<class ItemType>
void CircularList<ItemType>::displayList()
{
    cout << "\nThe circular list contains " << endl;
    for (int pos = 1; pos < listPtr->getLength(); pos++)
    {
        cout << listPtr->getEntry(pos) << endl;
    }

    cout << endl << endl;
}

#endif

LinkedList.h

#pragma once
#ifndef _LINKED_LIST
#define _LINKED_LIST

#include "ListInterface.h"
#include "Node.h"
#include <cassert>
#include "PrecondViolatedExcep.h"

template<class ItemType>
class LinkedList :public ListInterface<ItemType>
{
private:
    Node<ItemType>* headPtr;
    Node<ItemType>* tailPtr;
    int itemCount;
    Node<ItemType>* getNodeAt(int position) const;

public:
    LinkedList();
    LinkedList(const LinkedList<ItemType>& aList);
    virtual ~LinkedList();
    bool isEmpty() const;
    int getLength() const;
    bool insert(int newPosition, const ItemType& newEntry);
    bool remove(int position);
    void clear();
    ItemType getEntry(int position) const throw(PrecondViolatedExcep);
    void setEntry(int position, const ItemType& newEntry) throw(PrecondViolatedExcep);
};

template<class ItemType>
LinkedList<ItemType>::LinkedList() :headPtr(nullptr), tailPtr(nullptr), itemCount(0)
{}

template<class ItemType>
LinkedList<ItemType>::LinkedList(const LinkedList<ItemType>& aList):itemCount(aList.itemCount)
{
    Node<ItemType>* origChainPtr = aList.headPtr;
    if (origChainPtr == nullptr)
    {
        headPtr = nullptr;
    }
    else
    {
        headPtr = new Node<ItemType>();
        headPtr->setItem(origChainPtr->getItem());
        Node<ItemType>* newChainPtr = headPtr;
        origChainPtr = origChainPtr->getNext();
        while (origChainPtr != nullptr)
        {
            ItemType nextItem = origChainPtr->getItem();
            Node<ItemType>* newNodePtr = new Node(nextItem);
            newChainPtr->setNext(newNodePtr);
            newChainPtr = newChainPtr->getNext();
            origChainPtr = origChainPtr->getNext();
        }
        newChainPtr->setNext(nullptr);
    }
}

template <class ItemType>
LinkedList<ItemType>::~LinkedList()
{
    clear();
}

template<class ItemType>
bool LinkedList<ItemType>::isEmpty() const
{
    return itemCount == 0;
}

template<class ItemType>
int LinkedList<ItemType>::getLength() const
{
    return itemCount;
}

template<class ItemType>
bool LinkedList<ItemType>::insert(int newPosition, const ItemType& newEntry)
{
    bool ableToInsert = (newPosition >= 1) && (newPosition <= itemCount + 1);
    if (ableToInsert)
    {
        Node<ItemType>* newNodePtr = new Node<ItemType>(newEntry);
        if (newPosition == 1)
        {
            newNodePtr->setNext(headPtr);
            headPtr = newNodePtr;
        }
        else
        {
            Node<ItemType>* prevPtr = getNodeAt(newPosition - 1);
            newNodePtr->setNext(prevPtr->getNext());
            prevPtr->setNext(newNodePtr);
        }
        itemCount++;

    }
    return ableToInsert;
}

template<class ItemType>
bool LinkedList<ItemType>::remove(int position)
{
    bool ableToRemove = (position >= 1) && (position <= itemCount);
    if (ableToRemove)
    {
        Node<ItemType>* curPtr = nullptr;
        if (position == 1)
        {
            curPtr = headPtr;
            headPtr = headPtr->getNext();
        }
        else
        {
            Node<ItemType>* prevPtr = getNodeAt(position - 1);
            curPtr = prevPtr->getNext();
            prevPtr->setNext(curPtr->getNext());
        }

        curPtr->setNext(nullptr);
        delete curPtr;
        curPtr = nullptr;

        itemCount--;
    }

    return ableToRemove;
}

template <class ItemType>
void LinkedList<ItemType>::clear()
{
    while (!isEmpty())
    {
        remove(1);
    }
}

template<class ItemType>
ItemType LinkedList<ItemType>::getEntry(int position) const throw(PrecondViolatedExcep)
{
    bool ableToGet = (position >= 1) && (position <= itemCount);
    if (ableToGet)
    {
        Node<ItemType>* nodePtr = getNodeAt(position);
        return nodePtr->getItem();
    }
    else
    {
        string message = "getEntry() called with an empty list or invalid position.";
        throw (PrecondViolatedExcep(message));
    }
}

template<class ItemType>
void LinkedList<ItemType>::setEntry(int position, const ItemType & newEntry) throw(PrecondViolatedExcep)
{
    bool ableToSet = (position >= 1) && (position <= itemCount);
    if (ableToSet)
    {
        Node<ItemType>* nodePtr = getNodeAt(position);
        nodePtr->setItem(newEntry);
    }
    else
    {
        string message = "Invalid setEntry() call.";
        throw(PrecondViolatedExcep(message));
    }
}

template<class ItemType>
Node<ItemType>* LinkedList<ItemType>::getNodeAt(int position) const
{
    assert((position >= 1) && (position <= itemCount));
    Node<ItemType>* curPtr = headPtr;
    for (int skip = 1; skip < position; skip++)
        curPtr = curPtr->getNext();

    return curPtr;
}


#endif

Node.h

#pragma once
#ifndef _NODE
#define _NODE

template<class ItemType>
class Node
{
private:
    ItemType item;
    Node* next;

public:
    Node();
    Node(const ItemType& anItem);
    Node(const ItemType& anItem, Node* nextNodePtr);
    void setItem(const ItemType& anItem);
    void setNext(Node* nextNodePtr);
    ItemType getItem() const;
    Node* getNext() const;
};

template <class ItemType>
Node<ItemType>::Node() :next(nullptr)
{
} // end default constructor
template <class ItemType>
Node<ItemType>::Node(const ItemType& anItem) : item(anItem), next(nullptr)
{
} // end constructor
template <class ItemType> Node<ItemType>::Node(const ItemType& anItem, Node<ItemType>*
    nextNodePtr) : item(anItem), next(nextNodePtr)
{
} // end constructor
template <class ItemType> void Node<ItemType>::setItem(const ItemType& anItem)
{
    item = anItem;
} // end setItem
template <class ItemType>
void Node<ItemType>::setNext(Node<ItemType>* nextNodePtr)
{
    next = nextNodePtr;
} // end setNext
template <class ItemType> ItemType Node<ItemType>::getItem() const
{
    return item;
} // end getItem
template <class ItemType>
Node<ItemType>* Node<ItemType>::getNext() const
{
    return next;
} // end getNext
#endif

SortedListInterface.h

#pragma once
#ifndef _SORTED_LIST_INTERFACE
#define SORTED_LIST_INTERFACE

template <class ItemType>
class SortedListInterface
{
public:
    virtual void insertSorted(const ItemType& newEntry) = 0;
    virtual bool removeSorted(const ItemType& anEntry) = 0;
    virtual int getPosition(const ItemType& anEntry) = 0;
    virtual bool isEmpty() const = 0;
    virtual int getLength()const = 0;
    virtual bool remove(int position) = 0;
    virtual void clear() = 0;
    virtual ItemType getEntry(int position) = 0;
};
#endif

ListInterface.h

#pragma once
#ifndef _LIST_INTERFACE
#define _LIST_INTERFACE

template<class ItemType>
class ListInterface
{
public:
    virtual bool isEmpty() const = 0;
    virtual int getLength()const = 0;
    virtual bool insert(int newPosition, const ItemType& newEntry) = 0;
    virtual bool remove(int position) = 0;
    virtual void clear() = 0;
    virtual ItemType getEntry(int position) const = 0;
    virtual void setEntry(int position, const ItemType& newEntry) = 0;
};
#endif

PrecondViolatedExcep.h

#pragma once
#ifndef _PRECOND_VIOLATED_EXCEP
#define _PRECOND_VIOLATED_EXCEP

#include <stdexcept>
#include <string>

using namespace std;

class PrecondViolatedExcep :public logic_error
{
public:
    PrecondViolatedExcep(const string& message = "");
};
#endif

PrecondViolatedExcep.cpp

#pragma once
#include "PrecondViolatedExcep.h"

PrecondViolatedExcep::PrecondViolatedExcep(const string& message) :logic_error("Precondition Violated Exception: " + message)
{}

main.cpp

#include <iostream>
#include "CircularList.h"
#include "LinkedList.h"
#include "ListInterface.h"
#include "SortedListInterface.h"
#include <string>
using namespace std;

int main()
{
    CircularList<string>* listPtr= new CircularList<string>(6);
    cout << "The circular list size is: " << listPtr->getLength() << endl;
    string name1 = "Bob";
    string name2 = "Kate";  
    string name3 = "Jake";
    string name4 = "Alex";
    string name5 = "David";
    string name6 = "Mike";
    listPtr->insert(1, name1);
    listPtr->insert(8, name2);
    listPtr->insert(9, name3);
    listPtr->insert(4, name4);
    listPtr->insert(5, name5);
    listPtr->insert(6, name6);

    listPtr->displayList();

    cout << "The entry at position 2 in circular list is: " << listPtr->getEntry(2) << endl;
    listPtr->remove(1);
    cout << "The circular list content at position 1 is removed" << endl;
    cout << "Ana is inserted at position 4\n" << endl;
    listPtr->insert(4, "Ana");
    listPtr->displayList();

    system("pause");
    return 0;
}

The console output of running the application. It says there are 6 items, but it only prints 5.

我知道这可能要问的太多了,因为程序包含许多行代码,非常感谢,谢谢。

0 个答案:

没有答案