目录
栈LIFO
栈的数学性质 卡特兰(Catalan)数
n个元素进栈,出栈元素不同排列个数为
栈基本操作
InitStack(&S);//初始化一个空栈S
StackEmpty(S);//判断一个栈是否为空,若为空则返回true
Push(&S,x);//进栈,若栈S未满,则将x加入使之成为新栈顶
Pop(&S,&x);//出栈,若栈S非空,则弹出栈顶元素,并用x返回
GetTop(S,&x);//读栈顶元素,若栈S非空,则用x返回栈顶元素
DestroyStack(&S);//销毁栈,并释放栈S占用的存储空间
顺序栈的实现
#define MaxSize 50//定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize];//存放栈中的元素
int top;//栈顶指针
}SqStack;
栈空条件 S.top==-1;
栈满条件 S.top==MaxSize-1;
栈长:S.top+1;
初始化
void InitStack(SqStack &S){
S.top=-1;//初始化栈顶指针
}
判断栈空
bool StackEmpty(SqStack S){
if(S.top==-1)//栈空
return true;
return false;//非空
}
进栈
bool Push(SqStack &S,ElemType x){
if(S.top==MaxSize-1)//栈满 报错
return false;
S.data[++S.top]=x;//指针先加1,再入栈
return true;
}
出栈
bool Pop(SqStack &S,ElemType x){
if(S.top==-1)//栈空 报错
return false;
x=S.data[S.top--];//先出栈,指针再减1
return true;
}
读栈顶元素
bool GetTop(SqStack S,ElemType &x){
if(S.top==-1)//栈空 报错
return false;
x=S.data[S.top];//x记录栈顶元素
return true;
}
链式存储
typedef struct Linknode{
ElemType data;//数据域
struct Linknode *next;//指针域
}*LiStack;//栈类型定义
队列FIFO
基本操作
InitQueue(&Q);//初始化队列,构造一个空队列Q
QueueEmpty(Q);//判断队列空,若队列Q为空 则返回true
EnQueue(&Q,x);//入队,若队列Q未满,将z加入,使之成为新的队尾
DeQueue(&Q,&x);//出队,若队列Q非空,删除队头元素,并用x返回
GetHead(Q,&x);// 读队头元素,若队列Q非空,则将队头元素赋值给x
顺序存储
#define MaxSize 50//定义队列中元素的最大个数
typedef struct{
ElemType data[MaxSize];//存放队列元素
int front,rear;//队头指针,队尾指针
}SqQueue;
初始状态(队空条件):Q.front==Q.rear==0;
进队操作:队不满时,先送值到队尾元素,再将队尾指针加1
出队操作:队非空时,先取队头元素值,再将队头指针加1
循环队列
牺牲一个单元来区分队空和队满
队满条件:(Q.rear+1)%MaxSize==Q.front;
队空条件:Q.front==Q.rear;
队列中元素个数:(Q.rear-Q.front+MaxSize)%MaxSize;
循环队列的基本操作
初始化
void InitQueue(SqQueue &Q){
Q.rear=Q.front=0;//初始化队首、队尾指针
}
判空
bool isEmpty(SqQueue Q){
if(Q.rear==Q.front)return true;//队空条件
else return false;
}
入队
bool EnQueue(SqQueue &Q,ElemType x){
if((Q.rear+1)%MaxSize==Q.front)
return false;//队满 报错
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%MaxSize;//队尾指针加1,取模
return true;
}
出队
bool DeQueue(SqQueue &Q,ElemType &x){
if(Q.rear==Q.front)
return false;//队空 报错
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;//队头指针加1,取模
return true;
}
链式存储
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;//初始为空
}
判空
bool IsEmpty(LinkQueue Q){
if(Q.front==Q.rear)return true;
return false;
}
入队
void EnQueue(LinkQueue &Q,ElemType x){
LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=x;//创建新结点 插入到链尾
s->next=NULL;
Q.rear->next=s;
Q.rear=s;
}
出队
bool DeQueue(LinkQueue &Q,ElemType &x){
if(Q.front==Q.rear)return false;//队空
LinkNode *p=Q.front->next;
x=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;//若原队列中只有一个结点,删除后变空
free(p);
return true;
}
双端队列
栈、队列的应用
栈在括号匹配中的应用
栈在表达式求值中的应用
栈在递归中的应用
队列在层次遍历中的应用
队列在计算机系统中的应用