栈
后进先出,(LIFO
,last in first out)。
顺序栈
存储结构
typedef int ElemType;
const int INIT_SIZE = 100;
const int INCREAMENT_SIZE = 100;
typedef struct SqStack{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;
运算(初始化、入栈、出栈、栈空、栈长、取栈顶)
- 初始化
void InitStack(SqStack *S){ //这里用指针了,引用也行,随你的便
S->base = (ELemType*)malloc(sizeof(ElemtType)*INIT_SIZE);
S->top = S->base;
s->stacksize = INIT_SIZE;
}
- 栈空(StackEmpty)
int StackEmpty(SqStack S){
return S.top==S.base;
}
- 栈长(StackLength)
int StackLength(SqStack S){
return S.top-S.base;
}
- 入栈(Push)
void Push(SqStack *S,ElemType e){
if(s->top-s->base = s->stacksize) Increase(S); //栈满调用增长函数
*S->top++ = e; //插入到栈顶,并把top++
}
- 出栈(Pop)
void Pop(SqStack *S,ElemType &e){
if(StackEmpty(*S))PrintError(),return; //栈空
e = *--S->top; //top-1并把to栈顶元素带回,注意优先级的问题
}
- 取栈顶(GetTop)
void GetTop(SqStack S, ElemType &e){ //取栈顶,不修改,所以拷贝传参就行
if(!StackEmpty(S)){
e = *(S.top-1);
}
}
链栈(虽然书上一笔带过了)
用链表头插法
实现的栈,不带头结点
(你想带也行,没啥必要),注意Push
操作。
- 存储结构
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkStack;
- Push
void Push(LinkStack &top,ElemType e){ //top指针传过来,带头结点的话传的是S->next;
LNode *p = (LNode*)malloc(sizeof(LNode));
p->data = e;
p ->next = top->next;
top = p;
}
- Pop
void Pop(LinkStack &top,ElemType &e){
if(!StackEmpty()){
e = top->data;
LNode *t = top;
top = top->next;
free(t);
}
}
队列
先进先出,FIFO
,(First In First Out)
顺序队列(循环队列)
存储结构
const int MAXSIZE = 100;
typedef struct SqQueue{
ElemType *base;
int front;
int rear; //rear 指向队尾的下一位置
}SqQueue;
运算(初始化、队空、队满、队长、入队、出队)
- 初始化
void InitQueue(SqQueue &Q){
Q.base = (ElemType*)malloc(MAXSIZE*sizeof(ElemType));
Q.rear = Q.front = 0;
}
- 队空(QueueEmpty)
int QueueEmpty(SqQueue Q){
return Q.rear == Q.front;
}
- 队满(QueueFull,我编的)
int QueueFull(SqQueue Q){
return (Q.rear+1) % MAXSIZE == Q.front;
}
- 队长(QueueLength)
int QueueLength(SqQueue Q){
return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}
- 入队(
EnQueue
)
void EnQueue(SqQueue &Q, ElemType e){
if(!QueueFull(Q)){
Q.base[Q.rear+1] = e;
Q.rear = (Q.rear + 1) % MAXSIZE;
}
else
PrintError();
}
- 出队(
DeQueue
)
void DeQueue(SqQueue &Q,ElemType &e){
if(!QueueEmpty()){
e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXSIZE;
}
}
链队列
用链表实现的队列,封装链表的头指针和尾指针。
存储结构
typedef struct LinkQueue{
LNode *front; //front是头指针,指向头结点,有头结点哦
LNode *rear;
//int qLength; 可以封装一个长度
}LinkQueue;
运算(初始化、入队、出队)
- 初始化
void InitQueue(LinkQueue &Q){
Q.front = (LNode*)malloc(sizeof(LNode));
Q.rear = Q.front;
Q.front -> next = NULL;
//Q.qLength = 0;
}
- 入队
void EnQueue(LinkQueue &Q,ElemType e){
LNode *p = (LNode*)malloc(sizeof(LNode));
p->data = e;
Q.rear->next = p; //尾插
Q.rear = p;
}
- 出队(有个小
trick
)
void DeQueue(LinkQueue &Q,ElemType &e){
if(!QueueEmpty(Q)){
LNode* t = Q.front->next;
e = t->data;
Q.front->next = t->next;
if(Q.rear = t)Q.rear = Q.front; //当队列只剩一个元素,被删除时,rear会丢失
free(t);
}
}