链式队列
一、链式队列的设计思想:
首先一定要理解设计的初衷,就是队头队尾的位置要满足怎么快怎么设计,那么分析如下:
最终我们选择了入队,出队的时间复杂度都为O(1)的一种设计,也就是第四种设计,当然,头结点的数据域不使用,使用我们设计链式队列的头结点的时候删除数据域即可,链式队列的结构设计如下:
二、链式队列的结构设计
typedef struct LPNode //数据节点
{
int data; //数据
struct LPNode* next; //后继指针
}LPNode;
typedef struct HNode // 链式队列的头结点
{
struct LPNode* front; //队头指针,指向第一个数据节点
struct LPNode* rear; //队尾指针,指向最后一个数据节点
}HNode, *PLQueue;
三、链式队列的实现
cpp
//初始化
void InitQueue(PLQueue pq)
{
assert(pq != NULL);
pq->front = NULL;
pq->rear = NULL;
}
//入队
bool Push(PLQueue pq, int val)
{
assert(pq != NULL);
//申请节点
LPNode* p =(LPNode*)malloc(sizeof(LPNode));
p->data = val
p->next = NULL;
//插入
if(IsEmpty(pq))
{
pq->front = p;
pq->rear = p;
}else{
pq->rear->next = p;
pq->rear = p; //更新队尾指针
}
}
//获取队头的值但不删除
bool GetTop(PLQueue pq, int* rtval)
{
assert(pq != NULL);
if(IsEmpty(pq != NULL))
return false;
*rtval = pq->front->data;
return true;
}
//出队,获取队头的值并且删除
bool Pop(PLQueue pq, int* rtval)
{
assert(pq != NULL);
if(IsEmpty(pq))
return false;
*rtval = pq->front->data;
LPNode *p = pq->front;
pq->front = p->next;
free(p);
if(pq->front == NULL) //删除最后一个节点
pq->rear = NULL;
return true;
}
//获取长度
int GetLength(PLQueue pq)
{
assert(pq != NULL);
int count = 0;
LPNode *p = pq->front;
for(; p != NULL; p = p->next)
{
count++;
}
return count;
}
//判空
bool IsEmpty(PLQueue pq)
{
assert(pq != NULL);
return pq->front == NULL && pq->rear == NULL;
}
//销毁
void Destroy(PLQueue pq)
{
assert(pq != NULL);
LPNode *p;
while(pq->front != NULL)
{
p = pq->front;
pq->front = p->next;
free(p);
}
pq->rear = NULL;
}
四、链式队列的总结
- 带头结点,队头为第一个数据节点,队尾在最后一个数据节点
- 头结点为一个队头指针,一个队尾指针,增加队尾指针可以让入队的时间复杂度为O(1)