一.队列的特点:先进先出(FIFO)
数组与链表实现的对比:
1.用数组实现时,在数据出队列时需挪动整个数组 不方便
2.相较而言,链表实现队列较为简便
以下是用单向链表的方式实现队列
二.代码运行
三.代码实现
1.函数声明
#define QDataType int
//队列组成元素为节点,故定义一个QueueNode的节点类型
typedef struct QueueNode
{
QDataType _data ;
struct QueueNode* _next ;
}QueueNode;
//因为一个队列有头有尾,我们需要用到首尾指针,
//因此我们可以封装一个含头尾指针的结构体来作为我们的队列
typedef struct Queue
{
QueueNode* _head;
QueueNode* _tail;
}Queue;
//初始化队列
void InitQueue(Queue* pQ);
//打印队列
void PrintQueue(Queue* pQ);
//插入数据进队列
void PushQueue(Queue* pQ, QDataType x);
//删除数据
void PopQueue(Queue* pQ);
//队头数据
QDataType FrontQueue(Queue* pQ);
//队尾数据
QDataType BackQueue(Queue* pQ);
//队列是否为空,是返回1,否返回0
int EmptyQueue(Queue* pQ);
//销毁队列
void DestoryQueue(Queue* pQ);
#####2.函数实现
//初始化队列
void InitQueue(Queue* pQ)
{
pQ->_head = NULL;
pQ->_tail = NULL;
}
//打印队列
void PrintQueue(Queue* pQ)
{
assert(pQ);
QueueNode* cur = pQ->_head ;
printf("队头[ ");
while (cur != NULL)//遍历整个链表,打印元素
{
printf("%d ",cur->_data);
cur = cur->_next;
}
printf("]队尾\n");
}
//插入数据进队列
void PushQueue(Queue* pQ, QDataType x)
{
assert(pQ);
QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode)* 1);
if (newNode == NULL)
{
printf("内存已空,无法插入\n");
exit(-1);
}
//初始化节点
newNode->_data = x ;
newNode->_next = NULL;//初始化节点,指针域置为空
if (pQ->_head == NULL)
{
pQ->_head = newNode ;
pQ->_tail = newNode ;
}
else
{
pQ->_tail->_next = newNode ;
//newNode = pQ->_tail; 这句代码是将 tail的值赋给 newNode
//并没有起到改变尾的作用(tail里存的谁的值便指向谁)
pQ->_tail = newNode;
}
}
//删除数据,出队列
void PopQueue(Queue* pQ)
{
assert(pQ);
assert(pQ->_head);//如果pQ里无元素,则报错
QueueNode* head_next = pQ->_head->_next;//先找到头节点的下一个节点(以便释放头后仍能找到链表)
free(pQ->_head);//释放头节点
pQ->_head = head_next;//转换头节点
if (head_next == NULL)
{
pQ->_tail = NULL ;//进入这条语句,说明只有一个节点,删除后将尾置为空
}
}
//队头数据
QDataType FrontQueue(Queue* pQ)
{
assert(pQ);
assert(pQ->_head);
return pQ->_head->_data;
}
//队尾数据
QDataType BackQueue(Queue* pQ)
{
assert(pQ);
assert(pQ->_head);
return pQ->_tail->_data;
}
//队列是否为空,是返回1,否返回0
int EmptyQueue(Queue* pQ)
{
assert(pQ);
//该代码较为冗余
if (pQ->_head == NULL)
{
return 1;
}
else
{
return 0;
}
return pQ->_head == NULL ? 1 : 0;
}
//销毁队列
void DestoryQueue(Queue* pQ)
{
assert(pQ);
QueueNode* cur = pQ->_head ;
while (cur != NULL)
{
QueueNode* cur_next = cur->_next;
free(cur);
cur = cur_next;
}
pQ->_head = NULL;
pQ->_tail = NULL;
}
#####3.测试部分
int main()
{
Queue Q; //创建一个结构体Q 作为队列
InitQueue(&Q);
PushQueue(&Q, 10);
PushQueue(&Q, 5);
PushQueue(&Q, 10);
PushQueue(&Q, 8);
PrintQueue(&Q);
printf("表头数据为:[%d]\n",FrontQueue(&Q));
printf("表尾数据为:[%d]\n", BackQueue(&Q));
PopQueue(&Q);
PrintQueue(&Q);
PopQueue(&Q);
PopQueue(&Q);
PrintQueue(&Q);
PopQueue(&Q);
PrintQueue(&Q);
return 0;
}