栈和队列的特性,一个是先进后出,一个是先进先出。
对于栈来说,可以通过链表或者数组来进行实现 。
对于顺序栈来说,代码如下
//顺序栈类SeqStack的类定义
const int StackSize = 10; //10是示例性的数据,根据实际问题具体定义
template <typename DataType> //定义模板类SeqStack
class SeqStack
{
public:
SeqStack( ); //构造函数,初始化一个空栈
~SeqStack( ); //析构函数
void Push( DataType x ); //入栈操作,将元素x入栈
DataType Pop( ); //出栈操作,将栈顶元素弹出
DataType GetTop( ); //取栈顶元素(并不删除)
int Empty( ); //判断栈是否为空
private:
DataType data[StackSize]; //存放栈元素的数组
int top; //游标,栈顶指针,为栈顶元素在数组中的下标
};
//顺序栈类SeqStack的构造函数和析构函数
template <typename DataType>
SeqStack<DataType> :: SeqStack()
{
top = -1;
}
template <typename DataType>
SeqStack<DataType> :: ~SeqStack()
{
}
//顺序栈类SeqStack的入栈操作
template <typename DataType>
void SeqStack<DataType> :: Push(DataType x)
{
if (top == StackSize - 1) throw "上溢";
data[++top] = x;
}
//顺序栈类SeqStack的出栈操作
template <typename DataType>
DataType SeqStack<DataType> :: Pop( )
{
DataType x;
if (top == -1) throw "下溢";
x = data[top--];
return x;
}
//顺序栈类SeqStack的判空操作
template <typename DataType>
int SeqStack<DataType> :: Empty()
{
if(top == -1)
return 1;
else
return 0;
}
//顺序栈类SeqStack的取栈顶操作
template <typename DataType>
DataType SeqStack<DataType> :: GetTop( )
{
if(top == -1)
throw "下溢异常";
else
return data[top];
}
而另外的一种,链栈,则是
//链栈类LinkStack的类定义
template <typename DataType>
struct Node
{
DataType data; //数据域
Node<DataType> *next; //指针域
};
template <typename DataType>
class LinkStack
{
public:
LinkStack( ); //构造函数,初始化一个空链栈
~LinkStack( ); //析构函数,释放链栈各结点的存储空间
void Push(DataType x); //入栈操作,将元素x入栈
DataType Pop( ); //出栈操作,将栈顶元素出栈
DataType GetTop( ); //取栈顶元素(并不删除)
int Empty( ); //判空操作,判断链栈是否为空栈
private:
Node<DataType> *top; //栈顶指针即链栈的头指针
};
//链栈类LinkStack的构造函数
template <typename DataType>
LinkStack<DataType> :: LinkStack()
{
top = new Node<DataType>; //生成头结点
top->next = nullptr; //头结点的指针域置空
}
// 链栈类LinkStack的析构函数
template <typename DataType>
LinkStack<DataType> :: ~LinkStack()
{
Node<DataType> *q = nullptr;
while (top != nullptr) //释放链栈的每一个结点的存储空间
{
q = top; //暂存被释放结点
top = top->next; // top指向被释放结点的下一个结点
delete q;
}
}
//链栈类LinkStack的入栈操作
template <typename DataType>
void LinkStack<DataType> :: Push(DataType x)
{
Node<DataType> *s = nullptr;
s = new Node<DataType>; s->data = x; //申请结点s数据域为x
s->next = top; top = s; //将结点s插在栈顶
}
//链栈类LinkStack的出栈操作
template <typename DataType>
DataType LinkStack<DataType> :: Pop( )
{
Node<DataType> *p = nullptr;
DataType x;
if (top == nullptr) throw "下溢";
x = top->data; p = top; //暂存栈顶元素
top = top->next; //将栈顶结点摘链
delete p;
return x;
}
//链栈类LinkStack的取栈顶操作
template <typename DataType>
DataType LinkStack<DataType> :: GetTop()
{
if(top == nullptr)
throw "下溢异常";
else
return top->data;
}
//链栈类LinkStack的判空操作
template <typename DataType>
int LinkStack<DataType> :: Empty()
{
if(top == nullptr)
throw "下溢异常";
else
return 0;
}
同样的对于队列也有顺序存储和链式存储两种方式
顺序存储
//循环队列类CirQueue的类定义
const int QueueSize = 100; //100是示例性数据,根据需要重新定义
template <typename DataType> //定义模板类CirQueue
class CirQueue
{
public:
CirQueue( ); //构造函数,初始化空队列
~ CirQueue( ); //析构函数
void EnQueue(DataType x); //入队操作,将元素x入队
DataType DeQueue( ); //出队操作,将队头元素出队
DataType GetQueue( ); //取队头元素(并不删除)
int Empty( ); //判断队列是否为空
private:
DataType data[QueueSize]; //存放队列元素的数组
int front, rear; //游标,队头和队尾指针
};
//循环队列类CirQueue的构造函数
template <typename DataType>
CirQueue<DataType> :: CirQueue()
{
rear = front = QueueSize - 1;
}
//循环队列类CirQueue的析构函数
template <typename DataType>
CirQueue<DataType> :: ~CirQueue()
{
}
//循环队列类CirQueue的入队操作
template <typename DataType>
void CirQueue<DataType> :: EnQueue(DataType x)
{
if ((rear + 1) % QueueSize == front)
throw "上溢";
rear = (rear + 1) % QueueSize; //队尾指针在循环意义下加1
data[rear] = x; //在队尾处插入元素
}
//循环队列类CirQueue的出队操作
template <typename DataType>
DataType CirQueue<DataType> :: DeQueue( )
{
if (rear == front) throw "下溢";
front = (front + 1) % QueueSize; //队头指针在循环意义下加1
return data[front]; //读取并返回出队前的队头元素
}
//循环队列类CirQueue的取队头操作
template <typename DataType>
DataType CirQueue<DataType> :: GetQueue( )
{
if (rear == front) throw "下溢";
return data[(front + 1) % QueueSize]; //注意不修改队头指针
}
//循环队列类CirQueue的判空操作
template <typename DataType>
int CirQueue<DataType> :: Empty()
{
if(front == rear)
return 1;
else
return 0;
}
链式存储
//链队列类LinkQueue的类定义
template <typename DataType>
struct Node
{
DataType data; //数据域
Node<DataType> *next; //指针域
};
template <typename DataType>
class LinkQueue
{
public:
LinkQueue( ); //构造函数,初始化一个空的链队列
~LinkQueue( ); //析构函数,释放链队列各结点的存储空间
void EnQueue(DataType x); //入队操作,将元素x入队
DataType DeQueue( ); //出队操作,将队头元素出队
DataType GetQueue( ); //取链队列的队头元素
int Empty( ); //判断链队列是否为空
private:
Node<DataType> *front, *rear; //队头和队尾指针,分别指向头结点和终端结点
};
//链队列类LinkQueue的构造函数
template <typename DataType>
LinkQueue<DataType> :: LinkQueue( )
{
Node<DataType> *s = nullptr;
s = new Node<DataType>; s->next = nullptr; //创建头结点s
front = rear = s; //将队头指针和队尾指针都指向头结点s
}
//链队列类LinkQueue的析构函数
template <typename DataType>
LinkQueue<DataType> :: ~LinkQueue()
{
Node<DataType> *q = nullptr;
while (front != nullptr) //释放单链表的每一个结点的存储空间
{
q = front; //暂存被释放结点
front = front->next; // front指向被释放结点的下一个结点
delete q;
}
}
//链队列类LinkQueue的入队操作
template <typename DataType>
void LinkQueue<DataType> :: EnQueue(DataType x)
{
Node<DataType> *s = nullptr;
s = new Node<DataType>; //申请结点s
s->data = x; s->next = nullptr;
rear->next = s; rear = s; //将结点s插入到队尾
}
//链队列类LinkQueue的出队操作
template <typename DataType>
DataType LinkQueue<DataType> :: DeQueue( )
{
DataType x;
Node<DataType> *p = nullptr;
if (rear == front) throw "下溢";
p = front->next; x = p->data; //暂存队头元素
front->next = p->next; //将队头元素所在结点摘链
if (p->next == nullptr) rear = front; //判断出队前队列长度是否为1
delete p;
return x;
}
//链队列类LinkQueue的取队头操作
template <typename DataType>
DataType LinkQueue<DataType> :: GetQueue()
{
if(front == rear)
throw "下溢异常";
else
return front->next->data;
}
//链队列类LinkQueue的判空操作
template <typename DataType>
int LinkQueue<DataType> :: Empty()
{
if(front == rear)
return 1;
else
return 0;
}