总结学习栈与队列

栈和队列都是特殊的线性表,对线性表的插入与删除操作位置进行了限定。栈是一种先进后出的数据结构,只能在栈顶进行插入与删除;队列是一种先进先出的数据结构,只能在队尾查入队头删除。
与线性表一样,栈和队列都可以分别用顺序存储和链式存储的形式实现。
1.栈的顺序存储结构实现
设置空栈标志为栈顶指针top=-1,入栈top+1,出栈top-1。
template
class SeqStack
{
public:
SeqStack( ); //构造函数,初始化一个空栈
~SeqStack( ); //析构函数
void Push( DataType x ); //入栈操作,将元素x入栈
DataType Pop( ); //出栈操作,将栈顶元素弹出
DataType GetTop( ); //取栈顶元素(并不删除)
int Empty( ); //判断栈是否为空
private:
DataType data[StackSize]; //存放栈元素的数组
int top; //游标,栈顶指针,为栈顶元素在数组中的下标
};
(1)入栈push
template
void SeqStack :: Push(DataType x)
{
if (top == StackSize - 1) throw “上溢”;
data[++top] = x;
}
(2)出栈pop
template
DataType SeqStack :: Pop( )
{
DataType x;
if (top == -1) throw “下溢”;
x = data[top–];
return x;
}
构造函数和析构函数与线性表的实现并没有太大差异,不作赘述。
2.栈的链式存储结构实现
首先定义节点
template
struct Node
{
DataType data;
Node*next;
};
template
class LinkStack
{
public:
LinkStack( ); //构造函数,初始化一个空链栈
~LinkStack( ); //析构函数,释放链栈各结点的存储空间
void Push(DataType x); //入栈操作,将元素x入栈
DataType Pop( ); //出栈操作,将栈顶元素出栈
DataType GetTop( ); //取栈顶元素(并不删除)
int Empty( ); //判空操作,判断链栈是否为空栈
private:
Node *top; //栈顶指针即链栈的头指针
};
(1)入栈push
template
void LinkStack :: Push(DataType x)
{
Node *s = nullptr;
s = new Node; s->data = x; //申请结点s数据域为x
s->next = top; top = s; //将结点s插在栈顶
}
(2)出栈pop
template
DataType LinkStack :: Pop( )
{
Node *p = nullptr;
DataType x;
if (top == nullptr) throw “下溢”;
x = top->data; p = top; //暂存栈顶元素
top = top->next; //将栈顶结点摘链
delete p;
return x;
}
3.队列的顺序结构存储实现
为了更好的利用内存空间,我们使用循环队列实现队列的顺序存储。并且同时设置队首rear和队尾front指针,通过取模实现逻辑上的循环。即队满标志为(rear+1)%QueueSize=front,其中QueueSize为构建队列时申请的数组大小。队空的标志为rear=front。
const int QueueSize = 100; //100是示例性数据,根据需要重新定义
template //定义模板类CirQueue
class CirQueue
{
public:
CirQueue( ); //构造函数,初始化空队列
~ CirQueue( ); //析构函数
void EnQueue(DataType x); //入队操作,将元素x入队
DataType DeQueue( ); //出队操作,将队头元素出队
DataType GetQueue( ); //取队头元素(并不删除)
int Empty( ); //判断队列是否为空
private:
DataType data[QueueSize]; //存放队列元素的数组
int front, rear; //游标,队头和队尾指针
};
(1)构造函数
设置rear=front=QueueSize-1,一般在数组的高端。
(3)入队enqueue
template
void CirQueue :: EnQueue(DataType x)
{
if ((rear + 1) % QueueSize == front)
throw “上溢”;
rear = (rear + 1) % QueueSize; //队尾指针在循环意义下加1
data[rear] = x; //在队尾处插入元素
}
(4)出队dequeue
template
DataType CirQueue :: DeQueue( )
{
if (rear == front) throw “下溢”;
front = (front + 1) % QueueSize; //队头指针在循环意义下加1
return data[front]; //读取并返回出队前的队头元素
}
4.队列的链式存储结构实现
struct Node
{
DataType data; //数据域
Node *next; //指针域
};

template
class LinkQueue
{
public:
LinkQueue( ); //构造函数,初始化一个空的链队列
~LinkQueue( ); //析构函数,释放链队列各结点的存储空间
void EnQueue(DataType x); //入队操作,将元素x入队
DataType DeQueue( ); //出队操作,将队头元素出队
DataType GetQueue( ); //取链队列的队头元素
int Empty( ); //判断链队列是否为空
private:
Node *front, *rear; //队头和队尾指针,分别指向头结点和终端结点
};
(1)入队enqueue
template
void LinkQueue :: EnQueue(DataType x)
{
Node *s = nullptr;
s = new Node; //申请结点s
s->data = x; s->next = nullptr;
rear->next = s; rear = s; //将结点s插入到队尾
}
(2)出队dequeue
template
DataType LinkQueue :: DeQueue( )
{
DataType x;
Node *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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章