数据结构——队列

1.队列的结构与概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头

2.队列的代码实现

        队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数 组头上出数据,效率会比较低。

        2.1队列——链式结构体

// 链式结构:表示队列
typedef int QDataType ;                //定义数据类型
typedef struct QListNode                
{
    struct QListNode* next;              //记录下一个指针的地址
    QDataType data;                        //记录数据
}QNode;
// 队列的结构 记录
typedef struct Queue
{
    QNode* phead;                        //记录头部指针的位置
    QNode* tail;                             //记录末尾指针的位置
    int size;                                    //记录数据个数
}Queue;

        2.2队尾入队列

void QueuePush(Queue* q, QDataType data)
{    
    assert(q);                                        //判断q的有效性;
    QNode* set = (QNode*)malloc(sizeof(QNode));        //开辟一个QNode数据的空间
    if (!set)                                                                        //判断set是否开辟空间成功
    {
        printf("queuePush malloc err....");                          //失败即报错返回
        return;
    }
    set->data = data;                             //开辟空间成功后,把数据data写入                   
    set->next = NULL;                           //把set的next指针置空
    if (q->phead == NULL)                    //当phead为空的时候,说明这个时候是第一个数据入                                                                队列,头部指针和尾部指针都指向一个地址
    {
        q->phead = q->tail = set;             //所以q指向的phead与tail的地址相等与set;
    }
    else                                                //当不是第一个数据的时候,我们需要另外判断
    {
        q->tail->next = set;                    //将set插入在队列尾部,完成入队
        q->tail = q->tail->next;               //因为新插入数据,这里需要更新一下尾指针的地址。
    }
    q->size++;                                     //完成入队操作后,size别忘了要自增一下

        2.3队列首部出队列

void QueuePop(Queue* q)
{
    assert(q);                        
    assert(q->phead);        //这里需要判断一下phead的有效性,当没有数据的时候警告一下
    QNode* set = q->phead;                //创建一个指针记录一下phead的当前地址
    q->phead = q->phead->next;        //把phead指向的地址更新一下
    free(set);                                        //然后把set记录数据的空间给释放掉,完成出队操作
    set = NULL;
            //如果首元素free掉后,tail也应该置为null
    if (q->phead == NULL)        //当队列里完成出队操作后,队列里已经没有任何数据时
    {                                           //需要把tail指向的地址给更新置空,方便下次操作
        q->tail = NULL;
    }
    q->size--;                            //数据个数减1;

         2.4 获取队列头部元素 

QDataType QueueFront(Queue* q)
{
    assert(q);
    assert(q->phead);                //需要判断一下phead的有效性
    return q->phead->data;        //直接返回phead指向的data(首部数据元素)
}

         2.5获取队列队尾元素

QDataType QueueBack(Queue* q)
{
    assert(q);
    assert(q->tail);                 //需要判断一下tail的有效性
    return q->tail->data;        //直接返回tail指向的data(尾部数据元素)
}

        2.6获取队列中有效元素个数 

int QueueSize(Queue* q)
{
    assert(q);
    return q->size;        //直接返回q指向的size(记录的数据个数)
}

        2.7检测队列是否为空,如果为空返回非零结果,如果非空返回0 

bool QueueEmpty(Queue* q)
{
    assert(q);
    return q->phead == 0;        //直接返回判断结果;

        2.8销毁队列

void QueueDestroy(Queue* q)
{
    assert(q);
    QNode* set = q->phead;
    while (set)                                //与链表释放数据一样,释放直到set==null结束;
    {
        QNode* nex = set->next;
        free(set);
        set = nex;
    }
    q->tail = q->phead=NULL;        //释放的时候,把Queue里记录的数据给更新回档一下
    q->size = 0;

3.代码文本

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int QDataType ;
// 链式结构:表示队列 
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;

// 队列的结构 
typedef struct Queue
{
	QNode* phead;
	QNode* tail;
	int size;
}Queue;

// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

// 初始化队列 
void QueueInit(Queue* q)
{
	//断言q
	assert(q);
	q->phead = q->tail = NULL;
	q->size = 0;
}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* set = (QNode*)malloc(sizeof(QNode));
	if (!set)
	{
		printf("queuePush malloc err....");
		return;
	}
	set->data = data;
	set->next = NULL;
	if (q->phead == NULL)
	{
		q->phead = q->tail = set;
	}
	else
	{
		q->tail->next = set;
		q->tail = q->tail->next;
	}
	q->size++;
}
//  队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	assert(q->phead);
	QNode* set = q->phead;
	q->phead = q->phead->next;
	free(set);
	set = NULL;
	//如果首元素free掉后,tail也应该置为null
	if (q->phead == NULL)
	{
		q->tail = NULL;
	}
	q->size--;
}
// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->phead);
	return q->phead->data;
}
// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->tail);
	return q->tail->data;
}
// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
	assert(q);
	return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q)
{
	assert(q);
	return q->phead == 0;
}
// 销毁队列 
void QueueDestroy(Queue* q)
{
	assert(q);
	QNode* set = q->phead;
	while (set)
	{
		QNode* nex = set->next;
		free(set);
		set = nex;
	}
	q->tail = q->phead = NULL;
	q->size = 0;
}

4.总结 

        队列的核心思想是先进先出。

  • 44
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值