栈:只允许在表的末端进行插入和删除的线性表,这一段称为栈顶,不允许插入的一端称为栈底。
栈的顺序存储,简称顺序栈。
顺序栈的静态存储分配
#define maxSize 100
typedef char ElemType;
typedef struct {
ElemType elem[maxSize];
int top; //栈顶指针
}SeqStack;
顺序栈的动态存储分配
#define initSize 100
typedef char SElemType;
typedef struct {
SElemType elem[initSize];
int maxSize, top;
}SeqStack;
栈的基本操作
void InitStack(SeqStack*& s) {
s = (SeqStack*)malloc(sizeof(SeqStack));
s->top = -1;
}//初始化栈
void DestroyStack(SeqStack*& s) {
free(s);
}//销毁栈
bool StackEmpty(SeqStack* s) {
return (s->top == -1);
}//判空
bool Push(SeqStack*& s, SElemType e) {
if (s->top == s->maxSize - 1) {
return 0;
}
else {
s->top++;
s->elem[s->top] = e;
return 1;
}
}//进栈
bool Pop(SeqStack*& s, SElemType& e) {
if (s->top == -1) //出栈判空
return 0;
else {
e = s->elem[s->top]; //取栈顶元素
s->top--; //指针减一
return 1;
}
}//出栈
bool GetTop(SeqStack* s, SElemType& e) {
if (s->top == -1)
return 0;
else {
e = s->elem[s->top];
return 1;
}
}//取栈顶元素,注意,与出栈的差别仅仅是指针是否减一
例题:设计一个算法判定一个算术表达式中的圆括号是否正确配对, 并将对应的程序调试运行通过。 (提示:利用顺序栈)。
#include <stdio.h>
#include <malloc.h>
#include <string>
#include<iostream>
using namespace std;
#define initSize 100
typedef char SElemType;
typedef struct {
SElemType elem[initSize];
int maxSize, top;
}SeqStack;
void InitStack(SeqStack*& s) {
s = (SeqStack*)malloc(sizeof(SeqStack));
s->top = -1;
}//初始化栈
void DestroyStack(SeqStack*& s) {
free(s);
}//销毁栈
bool StackEmpty(SeqStack* s) {
return (s->top == -1);
}//判空
bool Push(SeqStack*& s, SElemType e) {
if (s->top == s->maxSize - 1) {
return 0;
}
else {
s->top++;
s->elem[s->top] = e;
return 1;
}
}//进栈
bool Pop(SeqStack*& s, SElemType& e) {
if (s->top == -1) //出栈判空
return 0;
else {
e = s->elem[s->top]; //取栈顶元素
s->top--; //指针减一
return 1;
}
}
//取栈顶元素,注意,与出栈的差别仅仅是指针是否减一
bool GetTop(SeqStack* s, SElemType& e) {
if (s->top == -1)
return 0;
else {
e = s->elem[s->top];
return 1;
}
}
//判断一个表达式括号是否配对
bool match(string exp) {
SeqStack* st;
InitStack(st); //初始化
char e;
int i = 0;
bool match = 1; //先假设它是配对的
while (i < exp.length() && match) {
if (exp[i] == '(') //如果是"(",进栈
Push(st, exp[i]);
else if (exp[i] == ')') { //否则是")",出栈并比对
if (GetTop(st, e) == 1) {
if (e != '(')
match = 0;
else
Pop(st, e); //出栈
}
else
match = 0; //无法取栈顶元素表示不匹配
}
i++; //除"("和")"外的字符跳过
}
if (!StackEmpty(st))
match = 0;
DestroyStack(st); //销毁
return match;
}
int main() {
string exp;
cin >> exp;
bool flag;
flag = match(exp);
if (flag)
printf("Yes");
else
printf("No");
return 0;
}
队列 :只允许在表的一端插入,在另一端删除。插入的一端叫队尾(rear),删除的一端叫对头(front)
循环队列结构的定义
#define initSize 100
typedef int QElemType;
typedef struct{
QElemType data[initSize];
int front; //队头指针
int rear; //队尾指针
int queuesize;
}LinkQueue;
链式队列结构定义如下
typedef int QElemType;
typedef struct node {
QElemType data;
struct node *link;
}LinkNode;
typedef struct {
LinkNode *front,*rear;
}LinkQueue;
队列的基本操作
void InitQueue(LinkQueue* Q) {
Q->front = 0;
Q->rear = 0;
}//初始化
int EnQueue(LinkQueue* Q, QElemType e) {
if ((Q->rear + 1) % initSize == Q->front) {
printf("队列已满");
return 0;
}
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % initSize;
return 1;
}//进队列
int DeQueue(LinkQueue* Q, QElemType& e) {
if (Q->front == Q->rear) {
printf("队列为空");
return 0;
}
e = Q->data[Q->front];
Q->front = (Q->front + 1) % initSize;
return 1;
}//出队列
int QueueEmpty(LinkQueue Q){
if(Q.front == Q.rear)
return 1;
else
return 0;
}//判空
int GetFront(LinkQueue Q, int e){
if(Q.front == Q.rear)//是否为空队列
return 0;
e = Q.data[Q.front];
return 1;
}//读队头元素
例题:试从键盘输入一整数序列a1,a2,…,an,请编程实现:当ai>0时,ai进队,当ai<0时,将队头元素出队,当ai=0时,表示输入结束。要求将队列处理成循环队列,入队和出队操作单独编写算法,并在异常情况下(如队满)时打印出错。
#include<stdio.h>
#include <malloc.h>
using namespace std;
#define initSize 100
typedef int QElemType;
typedef struct{
QElemType data[initSize];
int front;
int rear;
int queuesize;
}LinkQueue;
void InitQueue(LinkQueue* Q) {
Q->front = 0;
Q->rear = 0;
}
int EnQueue(LinkQueue* Q, QElemType e) {
if ((Q->rear + 1) % initSize == Q->front) {
printf("队列已满");
return 0;
}
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % initSize;
return 1;
}
int DeQueue(LinkQueue* Q, QElemType& e) {
if (Q->front == Q->rear) {
printf("队列为空");
return 0;
}
e = Q->data[Q->front];
Q->front = (Q->front + 1) % initSize;
return 1;
}
void Print(LinkQueue* Q) { //输出队列
if (Q->front == Q->rear) {
printf("队列为空");
}
QElemType x;
printf("Q->front->");
while (Q->front != Q->rear) {
x = Q->data[Q->front];
Q->front = (Q->front + 1) % initSize;
printf("%d->", x);
}
printf("Q->rear");
}
int Create(LinkQueue* Q) { //按要求插入、删除元素
int e;
for (int i = 0; i < initSize; i++) {
scanf_s("%d", &e);
if (e > 0) {
EnQueue(Q, e);
}
else if (e < 0) {
DeQueue(Q, e);
}
else
return 0;
}
}
int main() {
LinkQueue Q;
InitQueue(&Q);
Create(&Q);
Print(&Q);
return 0;
}