一、栈
只允许在一边进行插入或删除操作的线性表(后进先出LIFO)
顺序栈
(1)初始化
#define MaxSize 10
Typedef struct{
ElemType data[MaxSize];
int top; //栈顶指针 下标从0开始
}SqStack;
//初始化
void InitStack(SqStack &S)
{
S.top=-1; //栈为空
}
(2)进栈、出栈
//进栈
bool push(SqStack &s,ElemType x)
{
if(s.top==MaxSize-1) return 0;//栈满
s.top=s.top+1;
s.data[s.top]=x;
return 1;
}
//出栈
bool pop(SqStack &s,ELemType &x)
{
if(s.top==-1) return 0;// 栈空
x=s.data[s.top];
s.top=s.top-1;
return 1;
}
(3)查 获取栈顶
bool GetTop(SqStack s,ElemType &x)
{
if(s.top==-1) return 0;//栈空
x=s.data[s.top];
return 1;
}
链栈
(1)初始化
typedef struct LinkNode{
ElemType data;
struct LinkNode*next;
}LinNode,*LiStack;
bool InitStack(SqStack *s)
{
LinkNode *s=(LinkNode*)malloc(sizeof(SqStack));//开辟一个空间存储头结点
s==NULL;
return s;
}
(2)进栈、出栈(单链表 规定只在链头进行删除、插入操作)
//无头结点
bool push(SqStack *s,ElemType x) //入栈
{
if(s->length==MaxSize) return 0;
LinkNode *q=(LinkNode*)malloc(sizeof(SqStack));
q->data=x;
q->next=s->next;
s->next=q;
return 1;
}
bool pop(SqStack *s)// 出栈
{
if(s==NULL) return 0;
LinkNode *q=(LinkNode*)malloc(sizeof(SqStack));
q=s->next;
s->next=q->next;
free(q);
return 1;
}
(3)查
bool GetTop(LinkStack *s,ElemType &x)
{
if(s->Length==NULL) return 0;
x=s->data;
return x;
}
二、队列
只允许在线性表一端插入,在另一端删除(先进先出FIFO)
顺序存储
(1)初始化
#define MaxSize 10
typedef struct{
ElemType data[MaxSize];
int front,rear;
}SqQueue;
//初始化
void InitQueue(SqQueue *Q){
Q.rear==Q.front=0; //指向第0个位置 data[0]
}
(2)入队,出队(循环队列)
1.队空 Q.rear==Q.front
2.队满 (Q.rear+1)%MaxSize==Q.front (浪费一个存储空间)
3.队列长度 (Q.rear-Q.front+MaxSize)%MaxSize
//入队
bool Insert(SqQueue &Q,ElemType x)
{
if((Q.rear+1)%MaxSize==Q.front) return 0; //队满
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%MaxSize;//队尾指针移动到下一个空位置
return 0;
}
//出队
bool DeQueue(SqQueue &Q,ElemType &x)
{
if(Q.rear==Q.front) return 0;
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return 1;
}
(3)读队头元素
bool GetHead(SqQueue Q,ElemType &x)
{
if(Q.rear==Q.front) return 0;
x=Q.data[Q.front];
return 1;
}
链式存储
(1)初始化
typedef struct LinkNode{ //链式队列结点
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct{ //链式队列
LinkNode *front,*rear;
}LinkQueue;
//初始化
void InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
Q.front->next=NULL;
}
(2)出队、入队(循环队列)
//新元素入队
void EnQueue(LinkQueue &Q,ElemType x){
LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));//申请一个新节点
s->data=x;
s->next=NULL;
if(Q.rear==NULL){//如果为空队列 (不带头结点)
Q.front=s;
Q.rear=s;
}else{
Q.rear->next=s;//s插入到当前表尾结点的后一个为止
Q.rear=s; //队尾指针指向新队尾
}
}
//元素出队(不带头结点)
void DeQueue(LinkQueue &Q,ElemType &x){
if(Q.rear==Q.front) return 0;
LinkNode *p=Q.front;
x=p->data;
Q.front->next=p->next;
if(Q.rear==p){ //如果是最后一个节点出队
Q.front=NULL;
Q.front=NULL;
}
free(p);
return x;
}
(3)出队、入队(非循环队列,动态存储)
//带头结点
//入队
void EnQueue(LinkQueue *Q,ElemType x){
LNode *s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=NULL;
Q.rear->next=s;
Q.rear=s;
return true;
}
//出队
void DeQueue(LinkQueue *Q,ElemType &x){
if(Q.rear==Q.front){
return false;
}
LNode *p=Q.front->next; //p指向头结点的下一个节点(第一个元素)
x=p->data;
Q.front->next=p->next;
if(p==Q.rear){ //若p为最后一个节点
Q.rear=Q.front;
}
free(p);
return true;
}
借助 栈 实现 队列 逆置
void Reverse(LinkQueue *q,Stack *s){
int x;
if(!IsEmpty(q)){ //队列不为空
DeQueue(q,x); //将对头元素赋给x,删除对头元素
pushStack(s,x); //将x入栈
}
if(!IsEmpty(s)){
popStack(s,x);
EnQueue(q,x);
}
return true;
}