您的位置:首页 > 编程语言 > C语言/C++

C语言实现一个链式队列

2015-01-29 10:57 169 查看
定义

     队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表

  (1)允许删除的一端称为队头(Front)

  (2)允许插入的一端称为队尾(Rear)

  (3)当队列中没有元素时称为空队列

  (4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表

     队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头上的(不允许中途离队),即当前"最老的"成员离队。
 【例】在队列中依次加入元素a1,a2,…,an之后,a1是队头元素,an是队尾元素。退出队列的次序只能是a1,a2,…,an。

queue.h

#ifndef _QUEUE_H_
#define _QUEUE_H_
typedef int T;
typedef struct node *PNode;
typedef struct node{
T data;
PNode next;
}Node;

typedef struct{
PNode front;
PNode rear;
int size;
}Queue;

/*构造一个空队列*/
Queue *InitQueue();

/*销毁一个队列*/
void DestroyQueue(Queue *pqueue);

/*清空一个队列*/
void ClearQueue(Queue *pqueue);

/*判断队列是否为空*/
int IsEmpty(Queue *pqueue);

/*返回队列大小*/
int GetSize(Queue *pqueue);

/*返回队头元素*/
PNode GetFront(Queue *pqueue,T *pitem);

/*返回队尾元素*/
PNode GetRear(Queue *pqueue,T *pitem);

/*将新元素入队*/
PNode EnQueue(Queue *pqueue,T item);

/*队头元素出队*/
PNode DeQueue(Queue *pqueue,T *pitem);

/*遍历队列并对各数据项调用visit函数*/
void QueueTraverse(Queue *pqueue,void (*visit)());

#endif

queue.c
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include"queue.h"
/*构造一个空队列*/
Queue *InitQueue(){
Queue *queue=(Queue*)malloc(sizeof(Queue));
queue->front=NULL;
queue->rear=NULL;
queue->size=0;
}

/*销毁一个队列*/
void DestroyQueue(Queue *pqueue){
if(!IsEmpty(pqueue)){
ClearQueue(pqueue);
}
free(pqueue);
}

/*清空一个队列*/
void ClearQueue(Queue *pqueue){
while(!IsEmpty(pqueue)){
DeQueue(pqueue,NULL);
}
}

/*判断队列是否为空*/
int IsEmpty(Queue *pqueue){
if(0==pqueue->size&&NULL==pqueue->rear&&NULL==pqueue->front){
return 1;
}
else
return 0;
}

/*返回队列大小*/
int GetSize(Queue *pqueue){
assert(NULL!=pqueue);
return pqueue->size;
}

/*返回队头元素*/
PNode GetFront(Queue *pqueue,T *pitem){
if(!IsEmpty(pqueue)&&NULL!=pitem){
*pitem=pqueue->front->data;
}
return pqueue->front;
}

/*返回队尾元素*/
PNode GetRear(Queue *pqueue,T *pitem){
if(!IsEmpty(pqueue)&&NULL!=pitem){
*pitem=pqueue->rear->data;
}
return pqueue->rear;
}

/*将新元素入队*/
PNode EnQueue(Queue *pqueue,T item){
PNode pnode=(PNode)malloc(sizeof(Node));
if(NULL!=pnode){
pnode->data=item;
pnode->next=NULL;
if(IsEmpty(pqueue)){
pqueue->front=pnode;
}
else{
pqueue->rear->next=pnode;
}
pqueue->rear=pnode;
pqueue->size++;
}
return pnode;
}

/*队头元素出队*/
PNode DeQueue(Queue *pqueue,T *pitem){
PNode pnode=pqueue->front;
if(!IsEmpty(pqueue)&&NULL!=pnode){
if(NULL!=pitem){
*pitem=pnode->data;
}
pqueue->size--;
pqueue->front=pnode->next;
free(pnode);
if(0==pqueue->size){
pqueue->rear=NULL;
}
}
return pqueue->front;
}

/*遍历队列并对各数据项调用visit函数*/
void QueueTraverse(Queue *pqueue,void (*visit)()){
PNode pnode=pqueue->front;
int i=pqueue->size;
while(i--){
visit(pnode->data);
pnode=pnode->next;
}
}
test.c

#include<stdio.h>
#include"queue.h"
void print(T i)
{

printf("该节点元素为%d\n",i);
}
main()
{
Queue *pq = InitQueue();
int i,item;
printf("0-9依次入队并输出如下:\n");
for(i=0;i<10;i++)
{
EnQueue(pq,i);
GetRear(pq,&item);
printf("%d ",item);
}
printf("\n从队头到队尾遍历并对每个元素执行print函数:\n");
QueueTraverse(pq,print);
printf("队列中元素依次出队列并输出如下:\n");
for(i=0;i<10;i++)
{
DeQueue(pq,&item);
printf("%d ",item);
}
ClearQueue(pq);
if(IsEmpty(pq))
printf("\n将队列置空成功\n");
DestroyQueue(pq);
printf("队列已被销毁\n");
}

makefile
OBJECT =queue.o test.o
CC =gcc
CFLAG =-c

test:$(OBJECT)
$(CC) -o $@ $(OBJECT)
test.o:test.c queue.c queue.h
$(CC) $(CFLAG) -o $@ $<
queue.o:queue.c queue.h
$(CC) $(CFLAG) -o $@ $<
clean:
rm $(OBJECT) -rf

输出结果:
0-9依次入队并输出如下:
0 1 2 3 4 5 6 7 8 9
从队头到队尾遍历并对每个元素执行print函数:
该节点元素为0
该节点元素为1
该节点元素为2
该节点元素为3
该节点元素为4
该节点元素为5
该节点元素为6
该节点元素为7
该节点元素为8
该节点元素为9
队列中元素依次出队列并输出如下:
0 1 2 3 4 5 6 7 8 9
将队列置空成功
队列已被销毁
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: