数据结构---链队的实现
目录
- 链队---队列的链式表示和实现
- 链队列的结构定义
- 链队列的基本操作
- 1.初始化---构造一个只有头结点的空队列
- 2.清空队列---让队列重置成初始化的状态(头结点还存在,指针域为空)
- 3.销毁队列---整个队列不再存在(需释放头结点)
- 4.入队
- 5.出队
- 6.取队头元素
- 7.判断队列是否为空
- 8.求队列长度
链队---队列的链式表示和实现
链队是指采用链式存储结构实现的队列。结点删除移动头指针,结点添加移动尾指针,具有先进先出的特点
头指针---头结点 尾指针---尾结点
链队列的结构定义
typedef struct QNode
{
QElemType data; //队列元素
struct QNode *next;//指向下一元素结点
}QNode, *QueuePtr;
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear;//队尾指针
} LinkQueue;
链队列的基本操作
1.初始化---构造一个只有头结点的空队列
算法步骤
- 生成新结点作为头结点, 队头和队尾指针指向此结点。
- 头结点的指针域置空。
算法实现
void InitQueue(LinkQueue &Q)
{
QNode *QHead = new QNode;//构建头结点
Q.rear = Q.front = QHead; //初始头指针和尾指针,指向头结点
Q.front->next = Q.rear->next = NULL;//在使用前把指针域设置为NULL
}
2.清空队列---让队列重置成初始化的状态(头结点还存在,指针域为空)
算法步骤
- 将头尾指针都指向头结点
- 依次清空头结点后面结点的指针域和数据域
算法实现
void ClearQueue(LinkQueue &Q)
{
Q.rear = Q.front; //初始化为头尾都指向同一处(头结点)
QueuePtr p,q;//设置变量来进行指针的移动
p = Q.front->next;//p指向头结点下一结点
Q.front->next = NULL;//将头结点指针域置空
while(p) {
q = p;
free(q);
p = p->next;//p指针向后移动
}
}
3.销毁队列---整个队列不再存在(需释放头结点)
算法步骤
- 将头结点的指针域赋给尾结点(尾结点指向头结点下一结点)
- 释放原头结点
- 让头结点指向尾结点,重复以上步骤直至头结点为空
算法实现
void DestroyQueue(LinkQueue &Q)
{
while (Q.front) {
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
}
4.入队
算法步骤
- 为入队元素分配结点空间,用指针p指向。
- 将新结点数据域置为e。
- 将新结点插入到队尾 。
- 修改队尾指针为p。
算法实现
void EnQueue(LinkQueue &Q,QElemType e)
{
QueuePtr P = new QNode;//创建新节点
P->data = e;//把要插入的数据放进节点中
P->next = NULL;//因为在队尾插入,所以始终队尾的next为NULL
Q.rear->next = P;//把新节点放在当前队尾的后面
Q.rear = P;//然后更新队尾指针,指向新节点
}
5.出队
算法步骤
- 判断队列是否为空,若空则返回ERROR。
- 临时保存队头元素的空间,以备释放。
- 修改队头指针,指向下一个结点。
- 判断出队元素是否为最后一个元素,若是,则将队尾指针重新赋值, 指向头结点。
- 释放原队头元素的空间。
算法实现
void DeQueue(LinkQueue &Q,QElemType &e )
{
if (Q.rear == Q.front)//判断队列是否为空
return ERROR;
QueuePtr p;
p = Q.front->next;//使用p记录要被删除的节点
e = p->data;//把删除的节点的数据给e
Q.front->next = p->next;//头指针和p指向一致
//如果队列的最后一个元素被删除了,要让尾指针重新指向头结点
if (Q.rear == p)
{
Q.rear = Q.front;//就要让尾指针重新等于头指针
}
delete p;//最后释放那个被删除的节点
}
6.取队头元素
算法步骤
- 当队列非空时,此操作返回当前队头元素的值,头指针保持不变
算法实现
int GetHead{LinkQueue Q)
{
if(Q.front!=Q.rear) //队列非空
return Q.front->next->data;
}
7.判断队列是否为空
算法步骤
判断头指针尾指针是否都指向头结点
bool QueueEmpty(LinkQueue Q)
{
if (Q.rear == Q.front)
return true;
return false;
}
8.求队列长度
算法步骤
- 设置计数器,从首元结点开始累加
- 计数器从1开始累加,直到等于尾结点
算法实现
int QueueLength(LinkQueue Q)
{
QueuePtr p;
int i = 1;
p = Q.front->next;
while (p != Q.rear) {
cout<<"data:"<<p->data;
i++;
p = p->next;
}
return i;
}
眉目作山河