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

队列的链式储存结构,以及循环队列(C语言)。

2016-04-05 00:00 507 查看
摘要: 用链表表示的队列称为链队列,一个链队列需要指向队头和队尾的两个指针,才能唯一确定;循环队列:为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。这种循环队列可以以单链表的方式来在实际编程应用中来实现。

队列的链式储存结构如下:

#include<stdio.h>
#include<stdlib.h>
typedef int QElemType;
typedef int Status;
/*-----------单链队列---队列的链式储存结构-------------------------*/
typedef struct QNode {
QElemType data;   /*数据域*/
struct QNode *next;  /*指针域*/
}QNode,*QueuePtr;
typedef struct {
QueuePtr front;  /*队头指针*/
QueuePtr rear;   /*队尾指针*/
}LinkQueue;

常用算法:

Status InitQueue(LinkQueue *Q) /*构造一个空队列Q*/
{
Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q->front)exit(0);  /*储存分配失败*/
Q->front->next=NULL; /*头结点指针域指向null*/
return 1;
}
Status EnQueue(LinkQueue *Q,QElemType e)/*插入元素e为q的队尾元素*/
{
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
p->data=e;
p->next=NULL;
Q->rear->next=p;
Q->rear=p;
return 1;
}
Status Dequeue(LinkQueue *Q,QElemType *e)/*若队列不为空,则删除Q的队头元素,并返回其值*/
{
QueuePtr p;
p=Q->front->next;
*e=p->data;
Q->front->next=p->next;
if(Q->rear==p)Q->rear=Q->front;
free(p);
return 1;
}
Status queueEmpty(LinkQueue *Q)//若队列不为空,则返回1
{
QueuePtr p;
p=Q->front->next;
if(p->data)
{
return 1;
}
else return 0;

}
Status DestroyQueue(LinkQueue *Q)/*销毁队列Q*/
{
while(Q->front){
Q->rear=Q->front->next;
free(Q->front);
Q->front=Q->rear;
}
return 1;
}

测试函数:先入队0,1,2,3,4,5,6,7,8,然后岀队6个在入队0,1,2,3,4,5,6,7,8.在岀队6个。

void main()  /*测试函数*/
{
int i,e;
LinkQueue Q;
InitQueue(&Q);
for(i=0;i<9;i++)/*入队0~8*/
{
EnQueue(&Q,i);
}
printf("入队0~8后,岀队六个元素为:");
for(i=0;i<6;i++)/*岀队六个*/
{
Dequeue(&Q,&e);
printf("%d\t",e);
}
printf("\n");
for(i=0;i<9;i++)/*入队0~8*/
{
EnQueue(&Q,i);
}
printf("入队0~8后,岀队五个元素为:");
for(i=0;i<6;i++)/*岀队六个*/
{
Dequeue(&Q,&e);
printf("%d\t",e);
}
printf("\n");
DestroyQueue(&Q);/*销毁队列*/
system("pause");
}

测试结果如下:(应该是岀队六个元素)



循环队列:

#include<stdlib.h>
typedef int QElemType;
typedef int Status;
/*-------------循环队列-- 队列的顺序储存结构--------------*/
#define MAXQSIZE 100  /*最大队列长度*/
typedef struct{
QElemType *base; /*初始化动态分配的空间*/
int front;  /*如果队列不为空,指向头指针*/
int rear;  /*尾指针,如果队列不为空,指向下一个位置*/
}SqQueue;
Status InitQueue(SqQueue *Q)/*构造一个空队列*/
{
Q->base=(QElemType*)malloc (MAXQSIZE*sizeof(QElemType));
if(!Q->base)exit(0);
Q->front=Q->rear=0;
return 1;
}
Status EnQueue(SqQueue *Q,QElemType e)/*插入新元素*/
{
if((Q->rear+1)%MAXQSIZE==Q->front)return 0;
Q->base[Q->rear]=e;
Q->rear=(Q->rear+1)%MAXQSIZE;
return 1;
}
Status DeQueue(SqQueue *Q,QElemType *e)/*删除头元素,返回其值*/
{
if(Q->front==Q->rear) return 0;
*e=Q->base[Q->front];
Q->front=(Q->front+1)%MAXQSIZE;
return 1;
}

测试函数如上,注意去掉没有的函数。程序运行结果如上。

注意:

循环队列判断是否队满有三种方式:

加一个标志位。

空一位,判断时队尾指针加1取模。

加一个计数器。

------------------------------------------华丽分割线-----------------------------------------------------

学习数据结构记录,如有错误欢迎指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息