栈
是只允许在一端进行插入或者删除的线性表
每接触一种新的数据结构,要从其逻辑结构,存储结构,运算三方面着手。
n个不同元素进栈,出栈的方式有卡特兰数个。
栈的顺序存储方式
1 2 3 4 5
| #define Max 100 typedef struct Stack{ ELementType data[Max]; int top; }SqStack;
|
栈空:S.top=-1
。栈满:S.top==Max-1
。或者分别为0与Max
。
顺序栈的基本操作
- 初始化(设置top值)
- 入栈
- 出栈
- 读栈顶元素
- 判断空栈
- 销毁栈
队列
- 队头:出队列的一端
- 队尾:入队列的一段
顺序队列的存储方式
1 2 3 4 5 6
| #define Max 100 #define element int typedef struct Queue{ element data[Max]; int front,rear; }SeQueue;
|
顺序队列的基本操作
- 初始化:front与rear都为0
- 判空
- 插入:尾指针加一
- 删除:头指针加一
- 读取队头元素
顺序队列的假溢出问题
即是q.rear==Max
时并不能说明为空
循环队列
- 初始化:
q.front = q.rear = 0
- 判空:牺牲一个单元,
(q.rear+1)%Max == q.front
- 入队:
q.rear = (q.rear+1)%Max
- 出队:
q.front = (q.front+1)%Max
- 队列长度:
(q.rear+Max-q.front)%Max
队列的链式存储结构
- 存储类型
1 2 3 4 5 6 7
| typedef struct LinkNode{ ElemType data; struct LinkNode *next; }LinkNode; typedef struct { struct LinkNode *front,*rear; }LinkQueue;
|
- 操作(均带有头结点)
1 2 3 4
| LinkQueue InitQueue(LinkQueue *q){ q->front = q->rear = (LinkNode*)malloc(sizeof(LinkNode)); q->front->next = NULL; }
|
课本上使用了C++语言,这里讨论下点运算符与箭头运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
#include <iostream> struct LinkNode { int data; LinkNode* next; };
struct LinkQueue { LinkNode* front; LinkNode* rear; };
int main() { LinkQueue q; q.front = nullptr; q.rear = nullptr;
LinkQueue* qPtr = new LinkQueue(); qPtr->front = nullptr; qPtr->rear = nullptr;
(*qPtr).front = nullptr;
std::cout << "q.front: " << q.front << std::endl; std::cout << "qPtr->front: " << qPtr->front << std::endl;
delete qPtr; return 0; }
|
1 2 3 4 5 6 7 8
| #include <stdbool.h> bool IsEmpty(LinkQueue *q){ if(q->front == q->rear){ return true; }else{ return false; } }
|
1 2 3 4 5 6 7
| void InQueue(LinkQueue *q,element x){ LinkNode p = (LinkNode*)malloc(sizeof(LinkNode)); p->data = x; p->next = NULL; q->rear->next = p; q->rear = p; }
|
1 2 3 4 5 6 7 8 9 10 11 12
| bool OutQueue(LinkQueue *q,element *x){ if(q->front == q->rear){ return false; } LinkNode *p = q->front->next; x = p->data; q->front->next = p->next; if(p == q->rear){ q->front = q->rear; } free(p); }
|
双端队列与输入或输出受限的双端队列
经典括号匹配算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include <stdbool.h> #include <stdio.h> typedef struct { char data[30]; int top; }SeStack;
void InitStack(SeStack* s) { s->top = -1; }
bool IsEmpty(SeStack *s) { if (s->top == -1) { return true; } else { return false; } }
bool EnStack(SeStack* s, char x) { if (s->top == 29) { return false; } s->data[++(s->top)] = x; return true; }
bool DeStack(SeStack* s, char* x) { if (IsEmpty(s)) { return false; } *x = s->data[(s->top)--]; return true; }
bool Compare(char a[]) { SeStack s; InitStack(&s); char* ptr = a; while (*ptr != '\0') { if (*ptr == '[' || *ptr == '{') { EnStack(&s, *ptr); } else if (*ptr == ']' || *ptr == '}') { char temp; if (!DeStack(&s, &temp)) { return false; } if (temp == '{' && *ptr != '}' ||temp == '[' && *ptr != ']') { return false; } } ptr++; } return IsEmpty(&s); } int main(void) { printf("%d", Compare("{{}}")); }
|