1.初始化
同之前文章,在这里不对前置操作进行说明,比如头文件,源文件等等,在此只说明代码功能的实现逻辑。
c
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
不过在这里还要说明一点,由于在这里我们要修改指针,所以如果正常传参应该要传二级指针,不过我们在这里在此定义一个结构体用来存放我们要用的东西,这样既不用传二级指针使得代码繁琐,也更加方便操作,如下:
c
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType val;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Queue;
初始化没什么好说的,过
2.销毁
c
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* curr = pq->head;
while (curr)
{
QNode* next = curr->next;
free(curr);
curr = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
这里的逻辑较为简单:
- 用next来保存下一个节点
- free掉当前节点
- curr置为下一个节点依次循环
最后把头尾指针置为空即可。
3.插入
c
void QueuePush(Queue* pq, QDataType data)
{
assert(pq);
QNode* newhead = (QNode*)malloc(sizeof(QNode));
if (newhead == NULL)
{
perror("malloc fail");
return;
}
newhead->next = NULL;
newhead->val = data;
//无节点
if (pq->tail == NULL)
{
pq->head = pq->tail = newhead;
}
else
{
pq->tail->next = newhead;
pq->tail = newhead;
}
pq->size++;
}
- 首先判断新生成的节点是否有效
- 接下来把数据的值插入到新生成节点中
- 如果无节点,那么让头尾指针指向新节点
- else,让尾指针连着新节点,让尾指针置为指向newhead
- 最后size++即可
4.删除
c
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->size != 0);
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
if (pq->head == NULL)
{
pq->tail = NULL;
}
pq->size--;
}
- 用next指针保存下一个节点
- free当前节点
- 指向下一个节点
- size--
5.获取队尾和对头数据
c
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->size != 0);
return pq->head->val;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->size != 0);
return pq->tail->val;
}
很简单,没什么好说的。
6.获取元素个数
c
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
很简单。
7.判空
c
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
同样没什么好说的。