链式队列(无头结点)
注意事项:带头结点的链式队列在出队列时,出最后一个元素的与出其它元素不同,出非最后一个元素,队尾指针不变,一直指向第一个元素,当出最后一个元素时,队尾指针改变指向队头(也就是指向头结点),认真看看这里(这个例子并没看到带头结点方便)
//编译环境 VS2008
Queue.h
#pragma once
#include
#include
#include
typedef int DataType;
typedef struct Node
{
struct Node* _Pnext;
DataType _data;
}Node,*pNode;
typedef struct Queue
{
pNode _pHead;
pNode _pTail;
}Queue;
//初始化
void InitQueue(Queue * q);
//队列尾插
void QueuePush(Queue *q,DataType data);
//队列头删
void QueuePop(Queue *q);
//创建一个结点
pNode BuyNode(DataType data);
//队列是否为空
int QueueEmpty(Queue q);
//队列的大小
int QueueSize(Queue *q);
//队头元素
DataType Queuefront(Queue *q);
//队尾元素
DataType Queueback(Queue *q);
//销毁的队列
void QueueDestroy(Queue *q);
//Queue.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"
//初始化
void InitQueue(Queue* q)
{
assert(q);
q->_pHead = q->_pTail = BuyNode(0);
}
//队尾进元素
void QueuePush(Queue* q,DataType data)
{
assert(q);
q->_pTail->_Pnext = BuyNode(data); //这里很重要
q->_pTail = q->_pTail->_Pnext;
}
//队列头删
void QueuePop(Queue *q)
{
assert(q);
if(q->_pTail == q->_pHead)
{
printf("队列元素为空,无元素可删!!!\n");
return;
}
else
{
pNode pDel = q->_pHead->_Pnext;
q->_pHead->_Pnext = q->_pHead->_Pnext->_Pnext;
if(pDel == q->_pTail) //**重要***如果要出的元素是尾元素,这里需要为指针指向头,其他不需要改变尾指针的指向
q->_pTail = q->_pHead;
free(pDel); //pDel不需要再指向NULL;因为本来就是临时变量,调用完函数自动销毁
}
}
//判断队列是否为空
int QueueEmpty(Queue q) //这里可以传队列的地址,但是直接传队列已经足够
{ //因为复制的临时变量也可以查看队列是否为空
return NULL == q._pHead;
}
//队列的大小
int QueueSize(Queue *q)
{
pNode pCur = q->_pHead->_Pnext;
int count = 0;
assert(q);
while(pCur)
{
++count;
pCur = pCur->_Pnext;
}
return count;
}
//队头元素
DataType Queuefront(Queue *q)
{
assert(q);
if(NULL == q->_pHead->_Pnext)
{
printf("队列为空,无队头元素!!!\n");
assert(0);
}
return q->_pHead->_Pnext->_data;
}
//队尾元素
DataType Queueback(Queue *q)
{
assert(q);
if(NULL == q->_pTail)
{
printf("队列为空无队尾元素!!!\n");
assert(0);
}
return q->_pTail->_data;
}
//新建一个结点
pNode BuyNode(DataType data)
{
pNode pCur = (pNode)malloc(sizeof(Node));
if(NULL == pCur)
{
printf("结点申请失败!!!\n");
assert(0);
}
pCur->_data = data;
pCur->_Pnext = NULL;
return pCur;
}
//销毁队列
void QueueDestroy(Queue *q)
{
pNode pCur = q->_pHead;
assert(q);
while(pCur)
{
pCur = pCur->_Pnext;
free(q->_pHead);
q->_pHead = pCur;
}
q->_pTail = NULL;
}
///
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
//
#include "Queue.h"
void QueueTest();
int main()
{
QueueTest();
return 0;
}
void QueueTest()
{
Queue s;
InitQueue(&s);
QueuePush(&s,1); //给队列入四个元素
QueuePush(&s,2);
QueuePush(&s,3);
QueuePush(&s,4);
printf("队列元素的个数size = %d\n",QueueSize(&s)); //队列元素的个数
printf("队列队头元素 = %d\n",Queuefront(&s));//队列队头元素
printf("队列队尾元素 = %d\n",Queueback(&s)); //队列队尾元素
QueuePop(&s); //队列出两个元素
QueuePop(&s);
QueuePop(&s);
printf("队列元素的个数 = %d\n",QueueSize(&s));
printf("队列队头元素 = %d\n",Queuefront(&s));
printf("队列队尾元素 = %d\n",Queueback(&s));
printf("如果x打印为1,则为空反之不为空 x=%d\n",QueueEmpty(s)); //判断队列是否为空,0不为空
QueueDestroy(&s);
}