从数据结构角度看,栈和队列也是线性表,只不过是操作受限的线性表。
队列:操作限制在两端的线性表,一端进行插入操作,称为队尾;另一端进行删除操作,称为队头。
1.链式队列的描述
有两组数据需要描述,结点数据和头尾指针数据。
描述结点: 数据域+next指针域
描述头尾指针: front保存队头的前一个位置,rear保存队尾的下标
typedef int datatype;
//数据的结点
typedef struct node{
datatype data;
struct node * next;
}Qnode, * QnodePtr;
//存放front和rear
typedef struct queue{
QnodePtr front;//指向队头结点的前一个位置
QnodePtr rear;//指向队尾结点
}LinkQueue, * LinkQueue_t;
2.基本操作
2.1创建空链队
LinkQueue_t createLinkQueue()
{
//1.申请front和rear的空间
LinkQueue_t Q = (LinkQueue_t)malloc(sizeof(LinkQueue));
if(NULL == Q)
{
perror("malloc");
return NULL;
}
//2.申请头结点的空间并交给front
Q->front = (QnodePtr)malloc(sizeof(Qnode));
if(NULL == Q->front)
{
perror("malloc");
return NULL;
}
Q->front->next = NULL;
//3.将rear也指向这个头结点
Q->rear = Q->front;
return Q;
}
2.2判空
int isEmpty(LinkQueue_t Q)
{
return (Q->front == Q->rear)?1:0;
}
或者 判断一下头结点后面是不是空即可
int isEmpty(LinkQueue_t Q)
{
return (Q->front->next == NULL)?1:0;
}
2.3入队
int inLinkQueue(LinkQueue_t Q, datatype x)
{
//1.封装新结点
QnodePtr pnew = (QnodePtr)malloc(sizeof(Qnode));
if(NULL == pnew)
{
printf("入队:申请新结点空间失败\n");
return -1;
}
pnew->data = x;
pnew->next = NULL;
//2.入队
Q->rear->next = pnew;
Q->rear = pnew;
return 0;
}
2.4出队
int outLinkQueue(LinkQueue_t Q, datatype *x)
{
//非空则出
if(isEmpty(Q))
{
printf("队列已空");
return -1;
}
//1.保存出队结点
QnodePtr p = Q->front;
Q->front = p->next;
*x = Q->front->data;
free(p);
p = NULL;
return 0;
}
2.5打印输出
void showLinkQueue(LinkQueue_t Q)
{
QnodePtr p = Q->front;
while(p->next != NULL)
{
printf("%d ", p->next->data);
p = p->next;
}
printf("\n");
}
3.测试
int i;
datatype x;
LinkQueue_t Q = createLinkQueue();
if(NULL == Q)
{
printf("创建链式队列失败\n");
return -1;
}
for(i = 0; i < 10; i++)
{
inLinkQueue(Q, i);
}
#if 0
while(!isEmpty(Q))
{
outLinkQueue(Q, &x);
printf("%d ", x);
}
printf("\n");
#endif
showLinkQueue(Q);
return 0;