数据结构之队列详解

什么是队列?

队列(Queue)是一种基本的数据结构,它是一种先进先出(FIFO)的数据结构,它允许在一端插入元素,在另一端删除元素。队列的应用非常广泛,例如在操作系统中用于管理进程的调度,以及在网络中用于实现数据包的传输等。

队列的实现方式

队列可以使用数组或链表来实现。使用数组实现队列时,需要定义一个固定大小的数组,并使用两个指针来跟踪队列的头部和尾部。insert_queue 操作将元素添加到队列的尾部,而 delete_queue 操作则将队列的头部元素删除并返回。使用链表实现队列时,每个节点都包含一个数据元素和一个指向下一个节点的指针。insert_queue 操作将一个新节点添加到链表的尾部,而 delete_queue 操作则将头节点删除并返回其数据元素。

下面我们分别来看一下使用数组和链表实现队列的代码。

使用数组实现队列

以下是使用数组实现队列(循环队列)的示例代码:

#include <stdio.h>
#include <stdlib.h>

//构造循环队列
struct queue
{
    int data[20];//定义一个大小为20的数组,用于储存数据
    int size;//队列元素大小
    int front;//队头指针
    int rear;//队尾指针
};

//创建循环队列
struct queue *create()
{
    //创建队列
    struct queue *head = malloc(sizeof(struct queue));
    //赋初值
    head->size = 20;
    head->front = 0;
    //设置队头和队尾在同一个位置,作为初始条件
    head->rear = head->front;

    return head;
}

//插入——入队
void insert_queue(struct queue *head,int data)
{
    //判断满(判断条件,差一个为满)
    if((head->rear + 1) % head->size == head->front)
    {
        printf("队满\n");
        return;
    }
    //插入
	//在当前队尾位置插入
    head->data[head->rear] = data;
    //队尾指针向下移动一个位置
    head->rear++;
}

//删除——出队
void delete_queue(struct queue *head)
{
    //判断队列是否为空
    if(head-front == head->rear)
    {
        printf("队空\n");
        return;
    }
    //删除
	//删除当前数据,没有直接删除空间,只能覆盖原数据内容
    printf("出队元素:%d\n",head->data[head->front]);
    //队头指针向后移动一个位置
    head->front++;
}

//遍历
void show(struct queue *head)
{
    //从队头 遍历到 队尾
    for(int i = head->front;i != head->rear;)
    {
        printf("%d ",head->data[i]);
        i = (i+1) % head->size;
    }
    printf("\n");
}

//获取队列元素个数
int count(struct queue *head)
{
    return ((head->rear + head->size - head->frot) % head->size);
}

//主函数
int main()
{
	//创建队列
	struct queue * head = create();
	
	//遍历队列
	show(head);

	delete_queue(head);
	
	insert_queue(head,1);
	
	delete_queue(head);
	delete_queue(head);

	insert_queue(head,1);
	insert_queue(head,2);
	insert_queue(head,3);
	insert_queue(head,4);
	insert_queue(head,5);
	insert_queue(head,6);
	insert_queue(head,7);
	insert_queue(head,8);

	show(head);
	delete_queue(head);
	delete_queue(head);
	show(head);
	return 0;
}

在这个示例代码中,我们使用一个数组 data来存储队列中的元素,使用变量 front 和 rear 来跟踪队列的头部和尾部。在 insert_queue 操作中,我们首先检查队列是否已满,如果已满则输出队满信息。如果队列未满,则将元素添加到队列的尾部,并将 rear 指针上移一位。在 delete_queue 操作中,我们首先检查队列是否为空,如果为空则输出为空信息。如果队列非空,则将队列的头部元素删除并返回。在 show 操作中,则遍历获取队列中所有元素。在 count 操作中,我们计算队列中元素的数量,并返回。最后调用了主函数来进行了简单的测试顺序栈的插入、删除、遍历功能。

使用链表实现队列

以下是使用链表实现队列的示例代码:

#include <stdio.h>
#include <stdlib.h>

//构造结点
struct Node {
    int data;
    struct Node* next;
};

//构造队头、队尾指针
struct pque
{
    struct Node* front;
    struct Node* rear;
};

//创建链式队列,返回值为 队头队尾指针结构体
struct pque * create()
{
    //创建头结点,作为空队列开始
    struct Node *head = malloc(sizeof(struct Node));
    head->next = NULL;
    //创建队头和队尾指针
    struct pque *p = malloc(sizeof(struct pque));
    //设置队头队尾的初始值
    p->front = head;
    p->rear = p->front;
    return p;
}

//入队
void insert_que(struct pque *que,int data)
{
    //1、创建新结点
    struct Node *new = malloc(sizeof(struct Node));
    new->data = data;
    //2、修改队尾结点,插入下一个
	//通过队尾指针来找到最后结点
    new->next = que->rear->next;
    que->rear->next = new;
    //3、修改队尾指针,存储新结点地址
    que->rear = new;
    
    
}

//出队
void delete_que(struct pque *que)
{
    //为空
    if(que->front->next == NULL)
    {
        printf("队空\n");
        return;
    }
    //删除
	//1、存储要删除的结点
    struct Node *p = que->front->next;
    printf("出队元素:%d\n",p->data);
    //2、移动队头指针
    que->front->next = p->next;
    //如果队尾就是第一个,删除的是队尾,这时需要改变队尾指针
    if(p->next == que->rear)
    {
        que->rear = que->front;
    }
    //3、删除结点
    free(p);
}

//遍历
void show(struct pque *que)
{
    //p存储头结点地址
	struct Node * p = que->front;

	while( p->next != NULL )
	{
		p = p->next;
		printf("%d ",p->data);
	}
	printf("\n");
}

//主函数
int main()
{

	struct pque * que = create();

	show(que);

	delete_queue(que);

	insert_queue(que,1);
	insert_queue(que,2);
	insert_queue(que,3);
	insert_queue(que,4);
	insert_queue(que,5);
	insert_queue(que,6);
	insert_queue(que,7);

	show(que);

	delete_queue(que);

	delete_queue(que);

	show(que);
	insert_queue(que,20);
	show(que);

	return 0;
}

在这个示例代码中,我们使用一个链表来实现队列。每个结点包含一个数据元素和一个指向下一个节点的指针。构造了队头、队尾结构体用于指向结点。在 insert_queue 操作中,我们创建一个新节点,并将其指针指向当前的 rear 结点。然后将 rear 指针移动到新节点。在 delete_queue 操作中,我们首先检查队列是否为空,如果为空则输出为空信息。如果队列非空,则将 front 指针移动到下一个结点,则将队列的头部元素删除并输出。在 show 操作中,则遍历获取队列中所有元素。最后调用了主函数来进行了简单的测试顺序栈的插入、删除、遍历功能。

队列的应用场景

队列是一种非常有用的数据结构,它可以用于许多不同的应用程序。以下是一些常见的应用场景:

  • 进程调度:在操作系统中,队列用于管理进程的调度。每当一个进程被创建时,它被添加到就绪队列中,等待 CPU 时间片的分配。当一个进程完成时,它被添加到完成队列中。
  • 数据包传输:在网络中,队列用于实现数据包的传输。每当一个数据包到达时,它被添加到发送队列中,等待发送。当一个数据包被成功发送时,它被添加到接收队列中,等待接收方的处理。
  • 银行排队:在银行等服务场所中,队列用于管理客户的排队。每当一个客户到达时,他被添加到队列中,等待服务员的处理。当一个客户完成时,他被从队列中删除。

总结

队列是一种非常有用的数据结构,它可以用于许多不同的应用程序。队列可以使用数组或链表来实现,每种实现方式都有其优点和缺点。在实现队列的过程中,需要注意队列是否为空或已满,以及内存分配和释放等问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值