目录
1、队列定义
队列:是一种先进先出(FIFO)的线性表。在表的一端插入(表尾),另一端(表头)删除
队列Q = (a1,a2,a3,......,an)
逻辑结构:与线性表相同,仍为一对一关系
存储结构:顺序队或链队,以循环顺序队列更常见
运算规则:只能在队首和队尾运算,且访问结点时依照先进先出的原则
实现方式:关键是编写入队和出队操作,具体实现依顺序队或链队的不同而不同
2、案例引入
舞伴问题
3、顺序队列的基本操作
3.1 顺序队列的定义
#define MAXSIZE 100 //最大队列长度
Typedef struct{
QElemTYpe *base; //初始化的动态分配存储空间
int front; //头指针
int rear; //尾指针
}SqQueue
3.2 队列的顺序表示和实现
初始:front = rear = 0;
入队:base[rear]=x; rear++;
出队:x =base[front]; front++;
空栈标志:front == rear
3.3 假上溢
//假上溢的条件
front != 0;
rear = MAXQSIZE;
解决方法:
引入循环队列
base[0]接在base[MAXQSIZE-1]之后,若rear+1 == M,则令rear = 0;
实现方法:
利用模(mod,C语言中:%)运算
插入元素:
Q.base[Q.rear] =x;//插入元素放在尾指针指向的位置
Q.rear = (Q.rear + 1) % MAXSIZE
删除元素:
x = Q.base[Q.front];//头指针指向的元素赋值给x
Q.front = (Q.front + 1) % MAXSIZE
3.4 解决队空和队满条件相同的情况
由于队空和队满都是 front == rear
解决方案
1)另外设一个标志以区分队空、队满
2)另设一个变量,记录元素个数
3)少用一个元素空间
队满条件:(rear + 1)%MAXQSIZE == front
3.5 循环队列的初始化
Status InitQueue (SqQueue &Q){ Q.base = new QElemType[MAXQSIZE];//分配数组空间 if(!Q.base) exit(OVERFLOW); //存储配置失败 Q.front = Q.rear = 0; //头尾指针置为0,队列位空 return OK; }
3.6 求循环队列的长度
int QueueLength (SqQueue Q){ return(Q.rear-Q.front + MAXQSIZE) % MAXQSIZE }
3.7 循环队列 入队
Status EnQueue (SqQueue &Q,QElemType e){ if((Q.rear+1)%MAXQSIZE == Q.front) return ERROR;//队满 Q.base[Q.rear] =x;//插入元素放在尾指针指向的位置 Q.rear = (Q.rear + 1) % MAXSIZE //队尾指针加一 }
3.8 循环队列 出队
Status DeQueue (SqQueue &Q,QElemType &e){ if(Q.rear == Q.front) return ERROR;//队空 x = Q.base[Q.front];//头指针指向的元素赋值给x Q.front = (Q.front + 1) % MAXSIZE }
3.9 顺序队列取队头元素
SElemType GetHead(SqQuere Q){ if(Q.front != Q.rear)//队列不为空 return Q.base[Q.front];//返回队头指针元素的值,队头指针不变 }
4、链队的基本操作
4.1 链队的类型定义
#define MAXSIZE 100//最大队列长度
typedef struct Qnode{
QElemType data;
struct Qnode *next;
}QNode,*QuenePtr;
typedef struct{
QuenePtr front;//队头指针
QuenePtr rear;//队尾指针
}LinkQueue
4.2 链队列初始化
4.3 销毁链队列
4.4 将元素e入队
4.5 链队列出队