栈
定义:一种只能在一端进行插入和删除操作的线性表。
特点:先进后出(Last In First Out,LIFO),第一个出栈的元素始终是栈顶元素。
-
栈的存储结构
(1)顺序存储;
(2)链式存储; -
顺序存储结构的基本操作
(1)顺序存储的结构定义:typedef struct{ int data[MAXSIZE]; //MAXSIZE是已定义的变量,用于限定栈满时的元素个数; int top;//栈顶指针 }SqStack;
-
初始化栈
void InitStack(SqStack &S){ S.top=-1;//栈顶元素设置为-1即可; }
-
栈的判空
int IsEmpty(SqStack &S){ if(S.top==-1)//只需判断栈顶指针是否等于-1; return 1; else return 0; }
-
入栈
int Push(SqStack &S, int x){ if(S.top==S.MAXSIZE-1){ return 0;//入栈之前判断栈是否为满,为满则返回0; ++S.top;//不满,则栈顶指针+1;栈顶指针向上移; S.data[S.top]=x;//将元素入栈,插入到栈顶指针所指向的数据单元; return 1; }
-
出栈
int Pop(SqStack &S, int x){ if(S.top==-1)//出栈前先判断栈是否为空,为空则返回0; return 0; x=S.data[S.top];//出栈元素(必为栈顶元素)赋值与x; --S.top; return 1; }
队列
定义:一种插入操作在队尾,而删除操作在队头的线性表。
特点:先进先出(First In First Out,FIFO)。
-
队列的存储结构
(1)顺序存储;
(2)链式存储; -
链式队列
(1)链式队列的结构
需要两个指针。分别为队头指针-front和队尾指针-rear。
(2)链式队列的操作
入队和出队相当于单链表的插入和删除(可以参考链式存储博客),只需要修改队头指针和队尾指针。
入队时在队尾添加元素,需修改队尾指针;
出队时在队头删除元素,需修改队头指针; -
循环队列
(1)循环队列的结构
需要两个指针,分别为队头指针-front和队尾指针-rear;
队头指针指向队头元素,队尾指针指向队尾元素的后一个位置;typedef struct{ int data[MAXSIZE]; int front; int rear; }
(2)循环队列的三种状态
空循环队列、一般情况的循环队列、满循环循环队列;
(3)循环队列的空状态和满状态的判别
a.通常设置一个标志用来标记队列是空是满,例如,定义一个变量count,记录队列元素个素,count= = 0,队列为空,count= =MAXSIZE,队列为满;
b.rear= =front判断队列是否为空;(rear+1)%MAXSIZE= =front判断队列是否为满。
(注意:在队满时,实际上空出了一个元素的位置,因为rear是指向队尾的后一个位置)
-
循环队列的基本操作
(1)初始化循环队列void InitQuence(SQuence &Q){ Q.front =Q.rear=0;//队头指针和队尾指针同时指向0位置,此时队列为空; }
(2)循环队列判断为空
int QuenceEmpty(SQuence &Q){
if(Q.front==Q.rear)
return 0;
else
return 1;
}
(3)入队
int EnQuence(SQence &Q,int x){
if((Q.rear+1)%MAXSIZE==front){//入栈时,需判断队列是否为满,为满则不能入队;
return 0;
Q.data[Q.rear]=x;//队列为满,存入元素;
Q.rear=(Q.rear+1)%MAXSIZE;//移动队尾指针;
return 1;
}
(4)出队
int DeQuence(SQuence &Q,int x){
if(Q.rear==Q.front)//出栈时,需判断队列是否为空,为空则不能出队
return 0;
x=Q.data[Q.front]; //不为空时,出队元素存x;
Q.front=(Q.front+1)%MAXSIZE;//移动队头指针;
return 1;
}