3.1 栈
3.1.1栈的逻辑结构
1.栈的定义
栈是限定仅在表尾进行插入和删除操作的线性表。允许插入和删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈。
栈的操作特性:后进先出。
2.栈的抽象数据类型定义
ADT Stack
Data
栈中元素具有相同类型及后进先出特性,
相邻元素具有前驱和后继关系
Operation
InitStack
前置条件:栈不存在
输入:无
功能:栈的初始化
输出:无
后置条件:构造一个空栈
DestroyStack
前置条件:栈已存在
输入:无
功能:销毁栈
输出:无
后置条件:释放栈所占用的存储空间
Push
前置条件:栈已存在
输入:元素值x
功能:在栈顶插入一个元素x
输出:如果插入不成功,抛出异常
后置条件:如果插入成功,栈顶增加了一个元素
Pop
前置条件:栈已存在
输入:无
功能:删除栈顶元素
输出:如果删除成功,返回被删元素值,否则,抛出异常
后置条件:如果删除成功,栈减少了一个元素
GetTop
前置条件:栈已存在
输入:无
功能:读取当前的栈顶元素
输出:若栈不空,返回当前的栈顶元素值
后置条件:栈不变
Empty
前置条件:栈已存在
输入:无
功能:判断栈是否为空
输出:如果栈为空,返回1,否则,返回0
后置条件:栈不变
endADT
3.1.2 栈的顺序存储结构及实现
1.顺序栈
栈的顺序存储结构称为顺序栈。
2.顺序栈的实现
声明:
const int MAX_SIZE=100;
template <class DataType>
class seqStack
{
public:
seqStack( ) ;
~seqStack( );
void Push ( DataType x );
DataType Pop ( );
DataType GetTop ( );
bool Empty ( );
private:
DataType data[MAX_SIZE];
int top;
}
入栈算法:
template <class DataType>
void seqStack<DataType> ::Push ( DataType x)
{
if (top == MAX_SIZE-1) throw “溢出”;
data[++top] = x;
}
出栈算法:
template <class DataType>
DataType seqStack<DataType> :: Pop ( )
{
if (top == -1) throw “溢出”;
x = data[top--];
return x;
}
3.两站共享空间
使用一个数组来存储两个栈,让一个栈的栈底为该数组的始端,另一个栈的栈底为该数组的末端,两个栈从各自的端点向中间延伸。
声明:
const intStack_Size=100;
template<class DataType>
classBothStack
{
public:
BothStack( );
~BothStack( );
void Push(inti, DataType x);
DataType Pop(inti);
DataTypeGetTop(inti);
bool Empty(inti);
private:
DataType data[Stack_Size];
int top1,top2;
};
入栈算法:
template <class DataType>
void BothStack<DataType>::push(int i,DataType x)
{
if(top1==top2-1) throw"上溢";
if(i==1) data[++top1]=x;
if(i==2) data[--top2]=x;
}
3.1.3栈的链接存储结构及实现
1.栈的链接存储结构----链栈
链栈的类声明:
template<class DataType>
classLinkStack
{
public:
LinkStack( );
~LinkStack( );
void Push(DataType x);
DataType Pop( );
DataTypeGetTop( );
bool Empty( );
private:
Node<DataType>*top;
}
入栈算法:
template<class DataType>
void LinkStack<DataType>::Push(DataType x)
{
s = new Node<DataType>;
s->data = x;
s->next = top;
top = s;
}
出栈算法:
template<class DataType>
DataTypeLinkStack<DataType> ::Pop( )
{
if (top == NULL)
throw "下溢";
x = top->data;
p = top;
top = top->next;
delete p;
return x;
}
3.1.4 顺序栈和链栈的比较
时间性能:相同,都是常数时间O(1)。
空间性能:
总之,当栈的使用过程中元素个数变化较大时,用链栈是适宜的,反之,应该采用顺序栈。
3.2 队列
3.2.1队列的逻辑结构
1.队列的定义
ADT Queue
Data
队列中元素具有相同类型及先进先出特性,
相邻元素具有前驱和后继关系
Operation
InitQueue
前置条件:队列不存在
输入:无
功能:初始化队列
输出:无
后置条件:创建一个空队列
DestroyQueue
前置条件:队列已存在
输入:无
功能:销毁队列
输出:无
后置条件:释放队列所占用的存储空间
EnQueue
前置条件:队列已存在
输入:元素值x
功能:在队尾插入一个元素
输出:如果插入不成功,抛出异常
后置条件:如果插入成功,队尾增加了一个元素
DeQueue
前置条件:队列已存在
输入:无
功能:删除队头元素
输出:如果删除成功,返回被删元素值
后置条件:如果删除成功,队头减少了一个元素
GetQueue
前置条件:队列已存在
输入:无
功能:读取队头元素
输出:若队列不空,返回队头元素
后置条件:队列不变
Empty
前置条件:队列已存在
输入:无
功能:判断队列是否为空
输出:如果队列为空,返回1,否则,返回0
后置条件:队列不变
endADT
3.2.2 队列的顺序存储结构及实现
1.队列的顺序存储结构----循环队列
声明:
const intQueueSize=100;
template<class DataType>
class CirQueue
{
public:
CirQueue( );
~ CirQueue( );
void EnQueue(DataType x);
DataTypeDeQueue( );
DataTypeGetQueue( );
bool Empty( );
private:
DataType data[QueueSize];
int front,rear;
};
入队算法:
template<class DataType>
void CirQueue<DataType> ::EnQueue(DataType x)
{
if ((rear+1) % QueueSize == front) throw "上溢";
rear =(rear+1) % QueueSize;
data[rear] = x;
}
出队算法:
template<class DataType>
DataTypeCirQueue<DataType>::DeQueue( )
{
if (rear == front)throw "下溢";
front = (front + 1) % QueueSize;
returndata[front];
}
读取头元素:
template<class DataType>
DataTypeCirQueue<DataType>::GetQueue( )
{
if (rear == front)throw "下溢";
i = (front + 1) % QueueSize;
return data[i];
}
3.2.3 队列的链接存储结构及实现
1.队列的链接存储结构----链队列
2.链队列的实现
声明:
template<class DataType>
classLinkQueue
{
public:
LinkQueue( );
~LinkQueue( );
void EnQueue(DataType x);
DataTypeDeQueue( );
DataTypeGetQueue( );
bool Empty( );
private:
Node<DataType>*front, *rear;
};
构造函数算法:
template <class DataType>
LinkQueue<DataType>::LinkQueue( )
{
front = newNode<DataType>;
front->next =NULL;
rear = front;
}
入队:
template <class DataType>
void LinkQueue<DataType>::EnQueue(DataType x)
{
s = new Node<DataType>;
s->data = x;
s->next = NULL;
rear->next = s;
rear = s;
}
出队:
template<class DataType>
DataTypeLinkQueue<DataType>::DeQueue( )
{
if (rear == front)throw "下溢";
p =front->next;
x = p->data;
front->next =p->next;
if (p->next ==NULL) rear = front;
delete p;
return x;
}
3.2.4 循环队列和链队列的比较
时间性能:
空间性能: