栈和队列
栈
栈的定义
栈(stack)是限定仅在表尾进行插入和删除操作的线性表。
允许插入和删除的一端为栈顶(top),另一端为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表,简称 LIFO 结构。

栈的顺序存储结构
顺序栈:线性表顺序存储的简化

结构代码
typedef int ElemType;
struct SqStack {
ElemType data[MAXSIZE];
int top; // 栈顶指针
};
顺序栈代码实现
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 // 存储空间初始分配量
typedef int Status;
typedef int ElemType;
struct SqStack {
ElemType data[MAXSIZE];
int top; // 栈顶指针
};
// 构造一个空栈S
Status InitStack(SqStack* S) {
S->top = -1;
return OK;
}
// 把S置为空栈
Status ClearStack(SqStack* S) {
S->top = -1;
return OK;
}
// 栈S为空栈,则返回TRUE,否则返回FALSE
Status StackEmpty(SqStack S) {
if (S.top == -1) {
return TRUE;
}
else {
return FALSE;
}
}
// 返回S的元素个数,即栈的长度
int StackLength(SqStack S) {
return S.top + 1;
}
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
Status GetTop(SqStack S, ElemType* e) {
if (S.top == -1) {
return ERROR;
}
*e = S.data[S.top];
return OK;
}
// 插入元素e为新的栈顶元素
Status Push(SqStack* S, ElemType e) {
if (S->top == MAXSIZE - 1) {
return ERROR; // 栈满
}
S->top++;
S->data[S->top] = e;
return OK;
}
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status Pop(SqStack* S, ElemType* e) {
if (S->top == -1) {
return ERROR;
}
*e = S->data[S->top];
S->top--;
return OK;
}
// 从栈底到栈顶依次对栈中每个元素显示
Status StackTraverse(SqStack S) {
for (int i = 0; i < S.top; i++) {
cout << S.data[i] << " ";
}
cout << endl;
return OK;
}
int main()
{
SqStack s;
int e;
if (InitStack(&s) == OK) {
for (int i = 1; i <= 10; i++) {
Push(&s, i);
}
}
cout << "栈中元素依次为:";
StackTraverse(s);
Pop(&s, &e);
cout << "弹出的栈顶元素:" << e << endl;
cout << "栈空否(1:空 0:否):" << StackEmpty(s) << endl;
GetTop(s, &e);
cout << "栈顶元素:" << e << " 栈的长度为:" << StackLength(s) << endl;
ClearStack(&s);
cout<<"清空栈后,栈空否(1:空 0:否):"<< StackEmpty(s) << endl;
system("pause");
return 0;
}
两栈共享空间
数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,另一个栈为栈的末端。两个栈如果增加元素,就是两端点向中间延申。

结构代码
typedef int ElemType;
struct SqDoubleStack {
ElemType data[MAXSIZE];
int top1; // 栈1栈顶指针
int top2; // 栈2栈顶指针
};
两栈共享空间代码实现
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20
typedef int Status;
typedef int ElemType;
struct SqDoubleStack {
ElemType data[MAXSIZE];
int top1; // 栈1栈顶指针
int top2; // 栈2栈顶指针
};
// 构造一个空栈S
Status InitStack(SqDoubleStack* S) {
S->top1 = -1;
S->top2 = MAXSIZE;
return OK;
}
// 把S置为空栈
Status ClearStack(SqDoubleStack* S) {
S->top1 = -1;
S->top2 = MAXSIZE;
return OK;
}
// 若栈S为空栈,则返回TRUE,否则返回FALSE
Status StackEmpty(SqDoubleStack S) {
if (S.top1 == -1 && S.top2 == MAXSIZE) {
return TRUE;
}
return FALSE;
}
// 返回S的元素个数,即栈的长度
int StackLength(SqDoubleStack S) {
return (S.top1 + 1) + (MAXSIZE - S.top2);
}
// 插入元素e为新的栈顶元素
Status Push(SqDoubleStack* S, ElemType e, int stackNumber) {
if (S->top1 + 1 == S->top2) {
return ERROR; // 满栈
}
else {
if (stackNumber == 1) {
S->data[++S->top1] = e;
}
else {
S->data[--S->top2] = e;
}
}
}
// 栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status Pop(SqDoubleStack* S, ElemType* e, int stackNumber) {
if (stackNumber == 1) {
if (S->top1 == -1) {
return ERROR;
}
*e = S->data[S->top1--];
}
else {
if (S->top2 == MAXSIZE) {
return ERROR;
}
*e = S->data[S->top2++];
}
return OK;
}
Status StackTraverse(SqDoubleStack S) {
for (int i = 0; i <= S.top1; i++) {
cout<<S.data[i]<<" ";
}
for (int i = S.top2; i < MAXSIZE; i++) {
cout<<S.data[i]<<" ";
}
cout << endl;
return OK;
}
int main()
{
SqDoubleStack s;
int e;
if (InitStack(&s) == OK) {
for (int i = 1; i <= 5; i++) {
Push(&s, i, 1);
}
for (int i = MAXSIZE; i >= MAXSIZE - 2; i--) {
Push(&s, i, 2);
}
}
cout << "栈中元素依次为:";
StackTraverse(s);
cout << "当前栈中元素有:" << StackLength(s) << endl;
Pop(&s, &e, 2);
cout << "弹出的栈顶元素 e = " << e << endl;
cout << "栈空否(1:空 0:否):" << StackEmpty(s) << endl;
for (int i = 6; i <= MAXSIZE - 2; i++) {
Push(&s, i, 1);
}
cout << "栈中元素依次为:";
StackTraverse(s);
cout << "栈满否(1:否 0:满):" << Push(&s, 1, 1) << endl;
ClearStack(&s);
cout << "清空栈后,栈空否(1:空 0:否):" << StackEmpty(s) << endl;
system("pause");
return 0;
}
栈的链式存储结构
把栈顶放在单链表的头部。

结构代码
typedef int ElemType;
// 链栈结构
struct StackNode {
ElemType data;
struct StackNode* next;
};
struct LinkStack {
StackNode* top;
int count;
};
链栈代码实现
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20
typedef int Status;
typedef int ElemType;
// 链栈结构
struct StackNode {
ElemType data;
struct StackNode* next;
};
struct LinkStack {
StackNode* top;
int count;
};
// 构造一个空栈S
Status InitStack(LinkStack* S) {
S->top = new StackNode();
S->top->next = NULL;
S->count = 0;
return OK;
}
// 把S置为空栈
Status ClearStack(LinkStack* S) {
StackNode *p, *q;
p = S->top;
while (p)
{
q = p;
p = p->next;
delete q;
}
S->count = 0;
return OK;
}
// 若栈S为空栈,则返回TRUE,否则返回FALSE
Status StackEmpty(LinkStack S) {
if (S.count == 0) {
return TRUE;
}
return FALSE;
}
// 返回S的元素个数,即栈的长度
int StackLength(LinkStack S) {
return S.count;
}
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
Status GetTop(LinkStack S, ElemType* e) {
if (S.count == 0) {
return ERROR;
}
*e = S.top->data;
return OK;
}
// 插入元素e为新的栈顶元素
Status Push(LinkStack* S, ElemType e) {
StackNode* s = new StackNode();
s->data = e;
s->next = S->top;
S->top = s;
S->count++;
return OK;
}
// 栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status Pop(LinkStack* S, ElemType* e) {
StackNode* p;
if (StackEmpty(*S)) {
return ERROR;
}
*e = S->top->data;
p = S->top;
S->top = S->top->next;
delete p;
S->count--;
return OK;
}
Status StackTraverse(LinkStack S) {
StackNode* p;
p = S.top;
while (p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
return OK;
}
int main()
{
LinkStack s;
int e;
if (InitStack(&s) == OK) {
for (int i = 1; i <= 10; i++) {
Push(&s, i);
}
}
cout << "栈中元素依次为:";
StackTraverse(s);
Pop(&s, &e);
cout << "弹出的栈顶元素 e = " << e << endl;
cout << "栈空否(1:空 0:否):" << StackEmpty(s) << endl;
GetTop(s, &e);
cout << "栈顶元素: " << e << " 栈的长度为: " << StackLength(s) << endl;
ClearStack(&s);
cout << "清空栈后,栈空否(1:空 0:否):" << StackEmpty(s) << endl;
system("pause");
return 0;
}
队列
队列的定义
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。

队列的顺序存储结构:循环队列
队列顺序存储结构的缺点:元素出队列时的时间复杂度为 O(n)。

引入两个指针:front 指针指向对头元素,rear 指针指向队尾元素的下一个位置。

假溢出问题:数组存在空闲位置但发生了数组越界

所以引入了循环队列解决假溢出问题:把队列的头尾相接的顺序存储结构称为循环队列。
问题:front == rear 时队列可能为满也可能为空。
解决方法:当队列为空时,条件为:front = rear。当队列为满时,修改其条件,保留一个元素空间。

此时队列满的条件是:(rear + 1) % QueueSize == front。
计算队列长度的公式为:(rear - front + QueueSize) % QueueSize。
结构代码
typedef int ElemType;
struct SqQueue {
ElemType data[MAXSIZE];
int front; //头指针
int rear; //尾指针,若队列不为空,指向队列元素的下一个位置
};
循环队列的代码实现
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20
typedef int Status;
typedef int ElemType;
//循环队列的顺序存储结构
struct SqQueue {
ElemType data[MAXSIZE];
int front; //头指针
int rear; //尾指针
};
//初始化一个空队列Q
Status InitQueue(SqQueue* Q) {
Q->front = Q->rear = 0;
return OK;
}
//将Q清为空队列
Status ClearQueue(SqQueue* Q) {
Q->front = Q->rear = 0;
return OK;
}
//若队列Q为空队列,则返回TRUE,否则返回FALSE
Status QueueEmpty(SqQueue Q) {
if (Q.front == Q.rear) {
return TRUE;
}
return FALSE;
}
//返回Q的元素个数,也就是队列的当前长度
int QueueLength(SqQueue Q) {
return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}
//若队列不空,则用e返回Q的队头元素
Status GetHead(SqQueue Q, ElemType* e) {
if (Q.front == Q.rear) {
return ERROR;
}
*e = Q.data[Q.front];
return OK;
}
//若队列未满,则插入元素e为Q新的队尾元素
Status EnQueue(SqQueue* Q, ElemType e) {
if ((Q->rear + 1) % MAXSIZE == Q->front) {
return ERROR;
}
Q->data[Q->rear] = e; //元素e赋值给队尾
Q->rear = (Q->rear + 1) % MAXSIZE; //若到最后则转到数组头部
return OK;
}
//若队列不空,则删除Q中队头元素,用e返回其值
Status DeQueue(SqQueue* Q, ElemType* e) {
if (Q->front == Q->rear) {
return ERROR;
}
*e = Q->data[Q->front];
Q->front = (Q->front + 1) % MAXSIZE;
return OK;
}
//从队头到队尾依次对队列Q中每个元素输出
Status QueueTraverse(SqQueue Q) {
int i = Q.front;
while ((i + Q.front) != Q.rear) {
cout << Q.data[i] << " ";
i = (i + 1) % MAXSIZE;
}
cout << endl;
return OK;
}
int main()
{
Status j;
int l;
ElemType d;
SqQueue Q;
InitQueue(&Q);
cout << "初始化队列后,队列空否?(1:空 0:否): " << QueueEmpty(Q) << endl;
for (int i = 0; i < MAXSIZE - 1; i++) {
EnQueue(&Q, i);
}
cout << "队列长度为: " << QueueLength(Q) << endl;
cout << "现在队列空否?(1:空 0:否): " << QueueEmpty(Q) << endl;
cout << "连续" << MAXSIZE << "次由队头删除元素,队尾插入元素: " << endl;
for (int i = 1; i <= MAXSIZE; i++) {
DeQueue(&Q, &d);
cout << "删除的元素是: " << d << " 插入的元素: " << i + 100 << endl;
d = i + 100;
EnQueue(&Q, d);
}
l = QueueLength(Q);
cout << "现在队列中的元素为: " << endl;
QueueTraverse(Q);
if (l - 2 > 0) {
cout << "现在由队头删除" << l - 2 << "个元素" << endl;
}
while (QueueLength(Q) > 2)
{
DeQueue(&Q, &d);
cout << "删除的元素值为" << d << endl;
}
j = GetHead(Q, &d);
if (j) {
cout << "现在队头元素为: " << d << endl;
}
ClearQueue(&Q);
cout << "清空队列后, 队列空否?(1:空 0:否): " << QueueEmpty(Q) << endl;
}
队列的链式存储结构
只允许尾进头出的线性表的单链表,简称链队列。

结构代码
typedef int ElemType;
struct QNode { //结点结构
ElemType data;
QNode* next;
};
struct LinkQueue {
QNode* front; //队头指针
QNode* rear; //队尾指针
};
链队列的代码实现
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20
typedef int Status;
typedef int ElemType;
struct QNode { //结点结构
ElemType data;
QNode* next;
};
struct LinkQueue {
QNode* front; //队头指针
QNode* rear; //队尾指针
};
//构造一个空队列Q
Status InitQueue(LinkQueue* Q) {
Q->front = Q->rear = new QNode();
Q->front->next = NULL;
return OK;
}
//销毁队列Q
Status DestroyQueue(LinkQueue* Q) {
while (Q->front)
{
Q->rear = Q->front->next;
delete Q->front;
Q->front = Q->rear;
}
return OK;
}
//将Q清为空队列
Status ClearQueue(LinkQueue* Q) {
QNode* p, * q;
Q->rear = Q->front;
p = Q->front->next;
Q->front->next = NULL;
while (p)
{
q = p;
p = p->next;
delete q;
}
return OK;
}
//若Q为空队列,则返回TRUE,否则返回FALSE
Status QueueEmpty(LinkQueue Q) {
if (Q.front == Q.rear) {
return TRUE;
}
return FALSE;
}
//求队列的长度
int QueueLength(LinkQueue Q) {
int i = 0;
QNode* p = Q.front;
while (p != Q.rear)
{
i++;
p = p->next;
}
return i;
}
//队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
Status GetHead(LinkQueue Q, ElemType* e) {
if (Q.front == Q.rear) {
return ERROR;
}
*e = Q.front->next->data;
return OK;
}
//插入元素e为Q的新的队尾元素
Status EnQueue(LinkQueue* Q, ElemType e) {
QNode* p = new QNode();
p->data = e;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
return OK;
}
//队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR
Status DeQueue(LinkQueue* Q, ElemType* e) {
QNode* p;
if (Q->front == Q->rear) {
return ERROR;
}
p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p) {
Q->rear = Q->front; //若队头就是队尾,则删除后将rear指向头结点
}
delete p;
return OK;
}
//将队列元素从头到尾输出
Status QueueTraverse(LinkQueue Q) {
QNode* p = Q.front->next;
while (p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
return OK;
}
int main()
{
int i;
ElemType d;
LinkQueue q;
i = InitQueue(&q);
if (i) {
cout << "成功地构造了一个空队列!" << endl;
}
cout << "是否空队列?(1:空 0:否): " << QueueEmpty(q) << endl;
cout << "队列的长度为: " << QueueLength(q) << endl;
EnQueue(&q, 1);
EnQueue(&q, 2);
EnQueue(&q, 3);
cout << "插入3个元素(1,2,3)后,队列的长度为: " << QueueLength(q) << endl;
cout << "是否空队列?(1:空 0:否): " << QueueEmpty(q) << endl;
cout << "队列的元素依次为:";
QueueTraverse(q);
i = GetHead(q, &d);
if (i == OK) {
cout << "队头元素是:" << d << endl;
}
DeQueue(&q, &d);
cout << "删除了队头元素: " << d << endl;
i = GetHead(q, &d);
if (i == OK) {
cout << "新的队头元素是:" << d << endl;
}
ClearQueue(&q);
cout << "清空队列后, q.front = " << q.front << " q.rear = " << q.rear << " q.front->next = " << q.front->next << endl;
DestroyQueue(&q);
cout << "销毁队列后, q.front = " << q.front << " q.rear = " << q.rear << endl;
system("pause");
return 0;
}

浙公网安备 33010602011771号