栈和队列的算法复习
队列
队列的定义和概念
1. 定义 只能在表的一端(队尾)进行插入,在另一端(队头)进行删除运算的线性表
2. 逻辑结构 与线性表相同,仍为一对一关系
3. 储存结构 用顺序队列或链队存储均可
4.运算规则 先进先出(FIFO)
5.实现方式 关键是编写入队和出队函数,具体实现依顺序队或链队的不同而不同
基本操作:
(1) InitQueue (&Q) //构造空队列
(2) DestroyQueue (&Q) //销毁队列
(3) ClearQueue (&S) //清空队列
(4) QueueEmpty(S) //判空. 空--TRUE,
(5) QueueLength(Q) //取队列长度
(6) GetHead (Q,&e) //取队头元素,
(7) EnQueue (&Q,e) //入队列
(8) DeQueue (&Q,&e) //出队列
(9) QueueTraverse(Q,visit()) //遍历
队列的顺序表示--用线性表
#define M 100 //最大队列长度
Typedef struct {
QElemType *base; //初始化的动态分配存储空间
int front; //头指针
int rear; //尾指针
}SqQueue;
空队标志: front= =rear
入队: base[rear++]=x;
出队: x=base[front++];
线性表来储存队列的缺陷
存在假溢出
解决方式
解决的方法--循环队列
循环队列
#define MAXQSIZE 100 //最大长度
Typedef struct {
QElemType *base; //初始化的动态分配存储空间
int front; //头指针
int rear; //尾指针
}SqQueue;
循环队列初始化
Status InitQueue (SqQueue &Q){
Q.base =new QElemType[MAXQSIZE]
if(!Q.base) exit(OVERFLOW);
Q.front=Q.rear=0;
return OK;
}
求循环队列的长度
int QueueLength (SqQueue Q){
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
循环队列入队
Status EnQueue(SqQueue &Q,QElemType e){
if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
循环队列出队
Status DeQueue (LinkQueue &Q,QElemType &e){
if(Q.front==Q.rear) return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
小结
顺序存储队列的实现方案:
1、队尾固定为0下标的元素
缺点:入队列时需向后移动队列中的剩余元素
2、队头固定为0下标的元素
缺点:出队列时需向前移动队列中的剩余元素
3、队头队尾均不固定
优点:入出队列均无需移动元素
缺点:假溢出
4、循环队列
链队列
typedef struct QNode{
QElemType data;
struct Qnode *next;
}Qnode, *QueuePtr;
typedef struct {
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
初始化
Status InitQueue (LinkQueue &Q){
Q.front=Q.rear=(QueuePtr) malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}
销毁链队列
Status DestroyQueue (LinkQueue &Q){
while(Q.front){
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear; }
return OK;
}
判断链队列是否为空
Status QueueEmpty (LinkQueue Q){
return (Q.front==Q.rear);
}
求链队列的队头元素
Status GetHead (LinkQueue Q, QElemType &e){
if(Q.front==Q.rear) return ERROR;
e=Q.front->next->data;
return OK;
}
链队列入队
Status EnQueue(LinkQueue &Q,QElemType e){
p=(QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->data=e; p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
链队列出队
Status DeQueue (LinkQueue &Q,QElemType &e){
if(Q.front==Q.rear) return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p) Q.rear=Q.front;//(删除最后一个的特殊情况)
delete p;
return OK;
}