队列 和 栈 是 一种 受限制的 线性表。所以 他们的 实现方式 都 相差 无几。之前有过 链栈 和 链式线性表 的 实现经验,自然 写 链队 ,也毫无问题。
下面详细讲解每一段代码 的技术要点
下面是队列节点的数据结构
struct QueueNode
{
ElementType data;
QueueNode * next;
};
//生成一个节点
QueueNode * queueNodeMake(ElementType data){
QueueNode * pNode = (QueueNode *)malloc(sizeof(QueueNode));
if (pNode != NULL)
{
pNode->data = data;
pNode->next = NULL;
}
return pNode;
}
无论是 线性表,还是栈,队列的 节点 结构 都是 一个 数据元素 和 一个 后继指针的 经典结构。(可以加一个前驱,形成双向XXX)。
然后是 根据 数据元素 生成 一个 节点的 函数,这个 函数 需要 注意 :1.内存分配失败的问题 2.将节点 后继设置为NULL,减少出错的可能性。
下面是 队列 的 数据结构:
struct LinkQueue
{
QueueNode * front;//头指针
QueueNode * rear;//队尾
int len;
};
front 是 头指针,其后继节点 是 队头节点,
rear 指向 队尾节点。
len :队列长度;有 len 这个部分,是一个非常 优秀的 实现方案,简化了许多操作 ,使逻辑清晰。例如:1.在判断队列是否为空时 2. 判断队列长度时 3.在出队时,判断队列是否为空时。
但是 要 时刻 谨记 len 长度的变化问题 :1.出队时 减1 2.入队时 + 1 3.清空队列时, 清0
下面是 初始化 队列函数
E_State queueInit(LinkQueue * queue){
QueueNode * node = (QueueNode *) malloc(sizeof(QueueNode));
if (node == NULL)
{
return E_State_Error;
}
else
{
//初始头节点为NULL 很重要
node->next = NULL;
queue->front = queue->rear = node;
queue->len = 0;
return E_State_Ok;
}
}
这个函数 比较简单,只是 要注意 初始化 队列的 属性
queue->front = queue->rear = node;
queue->len = 0;
以及 头节点的 后继 设置 为NULL.