顾名思义:采用链式存储结构表示的队列称为链队列。即它是仅在表头删除和表尾插入的单链表。
为了操作方便,引入带头结点的单链表,链队列节点定义和队列定义如下
typedef struct node
{
int data;
struct node*next;
}qnode;
typedef struct
{
qnode*front;
qnode*rear;
}linkqueue;
linkqeueue*q;
当q->rear=q->front时,认为队列为空,因为是链式结构,理论上不存在所谓的队列满的问题(下一次讲讲循环队列的队满问题)
链队列的基本操作和顺序队列一样,所以先来看看链队列的综合操作吧。
代码
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
int data;
struct node*next;
}qnode;
typedef struct
{
qnode*front;
qnode*rear;
}linkqueue;
int initqueue(linkqueue *q)
{
q->front=(qnode*)malloc(sizeof(qnode));
if(q->front!=NULL)
{
q->rear=q->front;
q->front->next=NULL;
return 1;
}
else return 0;
}
int enterlinkqueue(linkqueue*q,int x)
{
qnode*newnode;
newnode=(qnode*)malloc(sizeof(qnode));
if(newnode!=NULL)
{
newnode->data=x;
newnode->next=NULL;
q->rear->next=newnode;
q->rear=newnode;
return 1;
}
else return 0;
}
int delinkqueue(linkqueue*Q,int*x)
{
qnode*q;
if(Q->front==Q->rear)
return 0;
q=Q->front->next;
Q->front->next=q->next;
if(Q->rear==q)
Q->rear=Q->front;
*x=q->data;
free(q);
return 1;
}
int gethead(linkqueue q,int*x)
{
if(q.front==q.rear)
return 0;
*x=q.front->next->data;
return 1;
}
void print(linkqueue*q)
{
qnode*p=q->front->next;
if(p==NULL)
printf("there is empty\n");
else {
printf("there is:");
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
putchar('\n');
}
}
int main()
{
int v,i,j,record,x,n;
linkqueue queue;
initqueue(&queue);
printf("\nthe in number n:");
scanf("%d",&n);
printf("you need input:\n");
for(i=1;i<=n;i++)
{
scanf("%d",&record);
enterlinkqueue(&queue,record);
}
print(&queue);
if(gethead(queue,&v)==0)
printf("the queue is empty");
else printf("the head is:%d",v);
printf("\nyou want to out number:");
scanf("%d",&j);
printf("the out number:\n");
for(i=1;i<=j;i++)
{
delinkqueue(&queue,&x);
printf("%d ",x);
}
putchar('\n');
print(&queue);
return 0;
}
运行截图:
总结
这一次的代码难度还是有一点点的,毕竟涉及到了前面所学过的基本的链表的操作知识,但是比起单链表的头插法、尾插法之类的(这里初始化采用的是尾插法),队列的代码难度就显得不是那般恐怖了,除了长长的应用之外,其他的倒没什么值得注意的地方,唯一需要点一下是学会使用引用、学会使用指针的正确赋值