题目
编写程序queue.h,用链表实现队列(或栈)类。在测试程序lab9_2.cpp中定义一个整型队列(或栈)对象,插入5个整数,压入队列(或栈),再依次取出并显示出来。
C++代码如下:
//node.h
#ifndef NODE_H//结点类模板
#define NODE_H
template<class T>
class linkedlist;//新添
template<class T>//新添
class node
{
private:
node<T>* next;//指向后继指针的结点
public:
T data;//数据域
node(const T& data, node<T>* next = 0);//构造函数
void insertAfter(node<T>* p);//在本结点之后插入一个同类的结点P
node<T>* deleteAfter();//删除本结点的后继结点,并返回其地址
node<T>* nextNode();//获取后继结点的地址
const node<T>* nextNode()const;//获取后继结点的地址
friend linkedlist<T>;//因操作需要将linkedlist<T>作为node的友元(新添)
};
template<class T>
node<T>::node(const T& data, node<T>* next/*=0*/) :data(data), next(next)
{
}
template<class T>
node<T>* node<T>::nextNode()
{
return next;
}
template<class T>
const node<T>* node<T>::nextNode()const
{
return next;
}
template<class T>
void node<T>::insertAfter(node<T>* p)
{
p->next = next;
next = p;
}
template<class T>
node<T>* node<T>::deleteAfter()
{
node<T>* tempPtr = next;
if (next == 0)return 0;
next = tempPtr->next;
return tempPtr;
}
#endif
//link.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>
using namespace std;
#include "node.h"
template<class T>
class linkedlist
{
private:
node<T>* front, * rear;//表头和表尾指针
node<T>* prevPtr, * currPtr;//记录表当前遍历位置的指针,由插入和删除操作更新
int size;//表中的元素个数
int position;//当前元素在表中的位置序号,由函数reset使用
//函数成员:
//生成新结点,数据域为item,指针域为ptrNext
node<T>* nextNode(const T& item, node<T>* ptrNext = NULL);
void freeNode(node<T>* p);//释放结点 (未用)
//将链表L复制到当前表(假设当前表为空)
//被复制构造函数和“operator=”调用
void copy(linkedlist<T>& L);//(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
public:
void print();//打印链表类里的数据及其数目(新添)
linkedlist();
linkedlist(linkedlist<T>& L);//复制构造函数(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
~linkedlist();
linkedlist<T>& operator=(linkedlist<T>& L);//重载赋值运算符(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
int getSize()const;//返回链表中的元素个数
bool isEmpty()const;//链表是否为空 (未用)
void reset(int pos = 0);//初始化游标的位置(第一位数的位置设为0)
void next();//使游标移动到下一个结点
bool endOfList()const;//游标是否到了链尾
int currentPosition(void);//返回游标当前的位置
void insertFront(const T& item);//在表头插入结点
void insertRear(const T& item);//在表尾添加结点
void insertAt(const T& item);//在当前结点之前插入结点
void insertAfter(const T& item);//在当前结点之后插入结点
T deleteFront();//删除头结点
void deleteCurrent();//删除当前结点
T& data();//返回对当前结点成员数据的引用
const T& data()const;//返回对当前结点成员数据的常引用
//清空链表:释放所有结点的内存空间。被析构函数和“operator ="调用
void clear();
};
template<class T>
node<T>* linkedlist<T>::nextNode(const T& item, node<T>* ptrNext)//生成新结点,数据域为item,指针域为ptrNext
{
node<T>* tempPtr = new node<T>(item, ptrNext);
return tempPtr;
}
template<class T>
void linkedlist<T>::freeNode(node<T>* p)//释放结点
{
delete p;
}
template<class T>
void linkedlist<T>::print()//打印链表类里的数据及其数目(新添)
{
reset();
while (!endOfList())
{
cout << data() << " ";
next();
}
cout << endl;
cout << "size=" << getSize() << endl;
}
template<class T>
linkedlist<T>::linkedlist()//构造函数
{
size = 0;
front = rear = new node<T>(0);
currPtr = prevPtr = front;
}
template<class T>
int linkedlist<T>::currentPosition(void)//返回游标当前的位置
{
node<T>* tempPtr = front->nextNode();
position = 0;
while (tempPtr != currPtr)
{
tempPtr = tempPtr->nextNode();
position++;
}
return position;
}
template<class T>
int linkedlist<T>::getSize()const//返回链表中的元素个数
{
return size;
}
template<class T>
T& linkedlist<T>::data()//返回对当前结点成员数据的引用
{
return currPtr->data;
}
template<class T>
const T& linkedlist<T>::data()const//返回对当前结点成员数据的常引用
{
return currPtr->data;
}
template<class T>
void linkedlist<T>::next()//使游标移动到下一个结点
{
prevPtr = currPtr;
currPtr = currPtr->nextNode();
}
template<class T>
bool linkedlist<T>::endOfList()const//游标是否到了链尾
{
if (currPtr == NULL)return true;
else return false;
}
template<class T>
bool linkedlist<T>::isEmpty()const//链表是否为空
{
if (front == rear)return true;
else return false;
}
template<class T>
void linkedlist<T>::reset(int pos)//初始化游标的位置(第一位数的位置设为0)
{
prevPtr = front;
currPtr = front->nextNode();
position = pos;
for (int i = 0; i < position; i++)
{
prevPtr = currPtr;
currPtr = currPtr->nextNode();
}
}
template<class T>
void linkedlist<T>::insertFront(const T& item)//在表头插入结点
{
prevPtr = currPtr;
currPtr = nextNode(item, front->nextNode());
front->next = currPtr;
if (rear == front)
{
rear = currPtr;
}
size++;
}
template<class T>
void linkedlist<T>::insertRear(const T& item)//在表尾添加结点
{
prevPtr = currPtr;
currPtr = nextNode(item, rear->nextNode());
rear->next = currPtr;
rear = currPtr;
size++;
}
template<class T>
void linkedlist<T>::insertAfter(const T& item)//在当前结点之后插入结点
{
prevPtr = currPtr;
node<T>* tempPtr = nextNode(item, currPtr->nextNode());
currPtr->next = tempPtr;
if (currPtr == rear)
{
rear = tempPtr;
}
currPtr = tempPtr;
size++;
}
template<class T>
void linkedlist<T>::insertAt(const T& item)//在当前结点之前插入结点
{
currPtr = nextNode(item, prevPtr->nextNode());
prevPtr->next = currPtr;
size++;
}
template<class T>
T linkedlist<T>::deleteFront()//删除头结点
{
currPtr = front->nextNode();
delete front;
front = currPtr;
size--;
return front->data;
}
template<class T>
void linkedlist<T>::deleteCurrent()//删除当前结点
{
node<T>* tempPtr = currPtr;
prevPtr->deleteAfter();
delete currPtr;
currPtr = prevPtr;
size--;
}
template<class T>
void linkedlist<T>::clear()//清空链表:释放所有结点的内存空间。被析构函数和“operator ="调用
{
node<T>* tempPtr = front->nextNode();
while (tempPtr != NULL)
{
node<T>* tempQ = tempPtr;
tempPtr = tempPtr->nextNode();
delete tempQ;
size--;
}
rear = front;
currPtr = prevPtr = front;
}
template<class T>
linkedlist<T>::~linkedlist()//析构函数
{
clear();
delete front;
}
template<class T>
void linkedlist<T>::copy(linkedlist<T>& L)//将链表L复制到当前表(假设当前表为空)被复制构造函数和“operator=”调用
//(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
{
//clear();
L.reset();
for (int i = 0; i < L.size; i++)
{
insertRear(L.data());
L.next();
}
}
template<class T>
linkedlist<T>& linkedlist<T>::operator =(linkedlist<T>& L)//重载赋值运算符(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
{
clear();
front->next = NULL;
copy(L);
cout << "调用重载运算符=" << endl;
return *this;
}
template<class T>
linkedlist<T>::linkedlist(linkedlist<T>& L)//复制构造函数(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
{
size = 0;
front = rear = new node<T>(0);
currPtr = prevPtr = front;
copy(L);
cout << "调用复制构造函数" << endl;
}
#endif
//queue.h
//queue.h
#ifndef QUEUE_CLASS
#define QUEUE_CLASS
#include <iostream>
#include <cstdlib>
using namespace std;
#include "link.h"
template <class T>
class Queue {
private: LinkedList<T> queueList;
public:
Queue(void);
void QInsert(const T& elt);
T QDelete(void);
T QFront(void);
int QLength(void) const;
int QEmpty(void) const;
void QClear(void);
};
template <class T>
Queue<T>::Queue(void)
{}
template <class T>
int Queue<T>::QLength(void) const
{
return queueList.ListSize();
}
template <class T>
int Queue<T>::QEmpty(void) const
{
return queueList.ListEmpty();
}
template <class T>
void Queue<T>::QClear(void)
{
queueList.ClearList();
}
template <class T>
void Queue<T>::QInsert(const T & elt)
{
queueList.InsertRear(elt);
}
template <class T> T Queue<T>::QDelete(void)
{
if (queueList.ListEmpty())
{
cerr << "Calling QDelete for an empty queue!" << endl;
exit(1);
}
return queueList.DeleteFront();
}
template <class T> T Queue<T>::QFront(void)
{
if (queueList.ListEmpty())
{
cerr << "Calling QFront for an empty queue!" << endl;
exit(1);
}
queueList.Reset();
return queueList.Data();
}
#endif // QUEUE_CLASS
//lab9_2.cpp
//lab9_2.cpp
#include "queue.h"
int main()
{
Queue<int> A;
for(int i=0;i<5;i++)
{
A.QInsert(i);
}
cout << " 队列 A 的元素为: ";
while (!A.QEmpty())
{
cout << A.QFront() << " ";
A.QDelete();
}
cout << endl;
}