我的指示是: 考虑一个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;
}
我知道这可能要问的太多了,因为程序包含许多行代码,非常感谢,谢谢。