队列
何为
队列和栈相反,遗址中先进先出的线性表,他的入队与出队分别在队列的俩头,即只允许一端插入元素,另一端删除元素,与现实中的队列一样
队列示意图:
入队端(队尾) 出队端(队头)
↓ ↓
┌─────┬─────┬─────┬─────┬─────┬─────┐
│ A │ B │ C │ D │ E │ │
├─────┼─────┼─────┼─────┼─────┼─────┤
← 插入元素方向 删除元素 →
(rear) (front)
队列的操作有:入队、出队、取队头元素、判队空/满
此处我们依旧使用C语言示例队列的增删查改
操作
1.初始化
在这里我们先定义队列节点结构体
typedef struct QNode{
int data;
struct QNode *next;
} QNode, *QueuePtr;
其中,我们定义了队列结构体的别名QNode,同时定义了指向结构体的指针别名QueuePtr
typedef struct{
QueuePtr front;//对头指针域
QueuePtr rear;//队尾指针域
} *LinkQueue;
由于我们要处理队头队尾,所以我们在这里定义了对头和队尾的指针
void InitQueue(LinkQueue Q){
Q->front = Q->rear = NULL;
printf("队列初始化成功!");
}
随后我们将队头和队尾都初始化为NULL,同时输出初始化成功
2.入队
void append(LinkQueue Q, int e){
QNode *p = (QNode *)malloc(sizeof(QNode));//申请空间
p->data = e;//把数据存储到数据域
p->next = NULL;//该节点的下一节点置空指向NULL
Q->rear->next = p;//队尾指针域的next指向新节点
Q->rear = p;
}
队列的入队操作,我们首先申请一个节点,然后把数据存储到数据域,同时将下一节点置空,然后队尾指针域的next指向新节点,最后将队尾指针域指向新节点
3.出队
// 出队
void pop(LinkQueue Q, int *e){
//判对空
if(Q == NULL || Q->front == NULL){
printf("队列为空!n");
}
QNode *p = Q->front; // 保存当前队头节点的地址
*e = p->data; // 将要删除节点的数据赋值给输出参数e
Q->front = p->next; // 将队头指针指向下一个节点,实现队头出队
// 如果删除的是最后一个节点(即删除后队列变空),则rear也需要置为NULL
if(Q->front == NULL) {
Q->rear = NULL;
}
free(p); // 释放被删除节点占用的内存空间
printf("元素 %d 出队成功n", *e); // 输出出队成功的提示信息
}
在出队的操作中,我们首先判对空,当队伍不为空时我们进行下一步操作
先定义一个*p指针指向对头,随后保存下对头的数据,然后队头指针指向下一个节点,如果删除的是最后一个节点,则队尾指针也置为NULL
最后释放要删除的节点
注意:在删除时,我们务必要先判断是否队空,否则会出问题!!!
4.取队头
void getHead(LinkQueue Q, int *e){
//判队空
if(Q == NULL || Q->front == NULL){
printf("队列为空!n");
}
*e = Q->front->data;
printf("队头元素为:%dn", *e);
}
5.遍历
void traverse(LinkQueue Q){
if(Q == NULL || Q->front == NULL){
printf("队列为空!n");
}
for(QNode *p = Q->front; p != NULL; p = p->next){
printf("%d ", p->data);
printf("n");
}
}
在for循环遍历中,我们从队头开始,通过指针域依次遍历,直至遍历至队尾指向NULL
写到这里的时候突然想到我不应该用int来定义然后return 0/return 1的,因为这里是一个个方法代表一个操作,处理都是在方法中的,所以返回值应该返回void
销毁队列
void destroy(LinkQueue Q) {
if(Q == NULL) {
printf("队列指针为空,无需销毁n");
return;
}
// 循环删除所有节点
while(Q->front != NULL) {
QNode *temp = Q->front; // 保存当前队头节点
Q->front = Q->front->next; // 移动队头指针到下一个节点
free(temp); // 释放当前节点内存
}
// 队列为空时,rear也应该为NULL
Q->rear = NULL;
printf("队列销毁成功!n");
}
总结
综上便是简单队列的一些简单的增删查改的一些操作了,但是还有一个循环队列和其他几个,可能要搁置一下,因为目前鄙人对队列还有一些不太清楚的,所以就先到这里了,后面会尽快补上的
完整代码可以在同文件夹下的./queque1.c中找到,博客会把代码附在评论区
感谢支持!
评论