队列是FIFO的数据结构。
队列的数组实现很简单,我觉得关关鍵点是在对队列的空和满的状态判断上。
对于队列的空和满的判断,我觉得有两种方案实现比较方便,
设队列的定义为
struct QueueRecord
{
int capacity;
int front;
int rear;
Element * array;
};
typedef struct QueueRecord * Queue;
capacity:队列动态分配的大小
front 队列前指针。
rear 队列尾指针
设有函数Succ(int val, Queue q)
val 是q中动态数组的下标,则next=Succ(v,q)表示v在q中的下一个位置。
引入这个是为了“循环使用”队列动态分配的数组,假如队列大小为7,当前尾指针
值为6(设队列申请的数组从0下标开始),则往队列再次插入值时,尾指针重设为0。
当然,能否插入要依据当前队列是否已经“满”.
判断空与满的方案有:
方案A:
rear指向下一个插入位置
当队列不为空时,front指向当前队列的第一个元素
front=rear时表示空,
front=Succ(rear)时表示满。
插入队列时,q->array[rear]=e;rear=Succ(rear)
出队时,front=Succ(front);
方案 B:
rear指向下一个插入位置
当队列不为空时,front-1指向当前队列的第一个元素
front-1=rear时表示空,
front=Succ(rear)+1时表示满。
插入队列时,q->array[rear]=e;rear=Succ(rear)
出队时,front=Succ(front);
下面给出方案A的实现:
/*ADT-头文件 AQ_queue.h*/
/**********************************
*author:Felix
*last update:Thu Jan 10 11:53:12 EST 2008
*description:
*
*
*
*/
#ifndef ___AQ_QUEUE___
#define ___AQ_QUEUE___
#include<stdio.h>
#include<stdlib.h>
#ifndef ___AQ_QUEUE_ELEMENT___
#define ___AQ_QUEUE_ELEMENT___
typedef int AQ_Element;
#endif
struct AQ_QueueRecord;
typedef struct AQ_QueueRecord * AQ_Queue;
int AQ_IsEmpty(AQ_Queue q);
int AQ_IsFull(AQ_Queue q);
AQ_Queue AQ_CreateQueue(int MaxElements);
void AQ_DisposeQueue(AQ_Queue q);
void AQ_MakeEmpty(AQ_Queue q);
void AQ_Enqueue(AQ_Element e,AQ_Queue q);
AQ_Element AQ_Front(AQ_Queue q);
void AQ_Dequeue(AQ_Queue q);
AQ_Element AQ_FrontAndDequeue(AQ_Queue q);
#define AQ_MIN_QUEUE_SIZE (5)
#endif
/****实现 文件 AQ_queue.c ****/
/**********************************
*author:Felix
*last update:Thu Jan 10 11:53:12 EST 2008
*description:
*consider define as follows:
* AQ_Queue q;
* It assumes that when q is full ,
* q->front= Succ(q->rear)
*and when empty
* q->front=q->rear
* That is
* if a queue is not empty
* q->front points to the front element
* q->rear points to the next position to insert into
*
*/
#include "AQ_queue.h"
struct AQ_QueueRecord
{
AQ_Element *array;
int capacity;
int front;
int rear;
};
static Succ(int val,AQ_Queue q)
{
return ++val%q->capacity;
}
int AQ_IsEmpty(AQ_Queue q)
{
return q->rear==q->front;
}
int AQ_IsFull(AQ_Queue q)
{
return Succ(q->rear,q)==q->front;
}
AQ_Queue AQ_CreateQueue(int MaxElements)
{
AQ_Queue q;
MaxElements=MaxElements>AQ_MIN_QUEUE_SIZE?MaxElements+1:AQ_MIN_QUEUE_SIZE+1;
q=(AQ_Queue)malloc(sizeof(struct AQ_QueueRecord));
if(q==NULL) return NULL;
q->array=(AQ_Element *)malloc(sizeof(AQ_Element)*MaxElements);
q->capacity=MaxElements;
q->rear=q->front=0;
return q;
}
void AQ_DisposeQueue(AQ_Queue q)
{
free(q->array);
free(q);
}
void AQ_MakeEmpty(AQ_Queue q)
{
q->rear=q->front=0;
}
void AQ_Enqueue(AQ_Element e,AQ_Queue q)
{
if(AQ_IsFull(q))return ;
q->array[q->rear]=e;
q->rear=Succ(q->rear,q);
}
AQ_Element AQ_Front(AQ_Queue q)
{
return q->array[q->front];
}
void AQ_Dequeue(AQ_Queue q)
{
if(AQ_IsEmpty(q))return ;
q->front=Succ(q->front,q);
}
AQ_Element AQ_FrontAndDequeue(AQ_Queue q)
{
AQ_Element e;
e=AQ_Front(q);
AQ_Dequeue(q);
return e;
}
/****测试文件*****/
/***main file for test : testAQ_queue.c*******/
/*///
*author:Felix
*create date:Thu Jan 10 13:32:57 EST 2008
*last update:Thu Jan 10 13:32:57 EST 2008
*description:
*
*
*//
#include "menu_c.h"
#include<stdio.h>
#include<stdlib.h>
#define AQ_TEST_SIZE 5
#include"AQ_queue.h"
int main()
{
AQ_Element e;
AQ_Queue q;
q=AQ_CreateQueue(AQ_TEST_SIZE);
while(SELECT())
{
switch (SELECTION)
{
/*Add an integer to queue.*/
case '1':
printf("integer to input:>");
scanf("%d",&e);
if(AQ_IsFull(q))printf("sorry,it's full now");
else
AQ_Enqueue(e,q);
break;
/*delete the front from queue*/
case '2':
if(AQ_IsEmpty(q))printf("node:no action as it's empty now");
else
AQ_Dequeue(q);
break;
/*show the front*/
case '3':
if(AQ_IsEmpty(q))printf("sorry,it's empty now");
else
printf("%d ",AQ_Front(q));
break;
/*Enqueue and show the fron till the queue is empty*/
case '4':
while(!AQ_IsEmpty(q))printf("%d ",AQ_FrontAndDequeue(q));
break;
case '9':
system("less ../AQ_queue.h");
break;
default:break;
}
}
return 0;
}
/***menu_c.h****/
/*///
*author:Felix
*create date:Thu Jan 10 13:32:57 EST 2008
*last update:Thu Jan 10 13:32:57 EST 2008
*description:
*
*
*/
#include <stdio.h>
#ifndef __MENU____
#define __MENU____
#define SELECT() ((___sel=___select())!='0')
#define SELECTION ___sel
char ___sel;
char ___select();
/*
define the menu:
*/
#endif
/***menu_c.c*****/
/*///
*author:Felix
*create date:Thu Jan 10 13:32:57 EST 2008
*last update:Thu Jan 10 13:32:57 EST 2008
*description:
*
*
*/
#include "menu_c.h"
char *___menu[]={
"1.Add an integer to queue.",
"2.delete the front from queue",
"3.show the front",
"4.Enqueue and show the fron till the queue is empty", "9.Print the file AQ_queue.h",
"0.EXIT",
NULL
};
void ___showMenu()
{
printf("please select:/n");
char **p=___menu;
while(*p)printf("%s/n",*p++);
printf(":>");
}
char ___select()
{
char c;
___showMenu();
while((c=getchar())=='/n');
return c;
}
队列的数组实现很简单,我觉得关关鍵点是在对队列的空和满的状态判断上。
对于队列的空和满的判断,我觉得有两种方案实现比较方便,
设队列的定义为
struct QueueRecord
{
int capacity;
int front;
int rear;
Element * array;
};
typedef struct QueueRecord * Queue;
capacity:队列动态分配的大小
front 队列前指针。
rear 队列尾指针
设有函数Succ(int val, Queue q)
val 是q中动态数组的下标,则next=Succ(v,q)表示v在q中的下一个位置。
引入这个是为了“循环使用”队列动态分配的数组,假如队列大小为7,当前尾指针
值为6(设队列申请的数组从0下标开始),则往队列再次插入值时,尾指针重设为0。
当然,能否插入要依据当前队列是否已经“满”.
判断空与满的方案有:
方案A:
rear指向下一个插入位置
当队列不为空时,front指向当前队列的第一个元素
front=rear时表示空,
front=Succ(rear)时表示满。
插入队列时,q->array[rear]=e;rear=Succ(rear)
出队时,front=Succ(front);
方案 B:
rear指向下一个插入位置
当队列不为空时,front-1指向当前队列的第一个元素
front-1=rear时表示空,
front=Succ(rear)+1时表示满。
插入队列时,q->array[rear]=e;rear=Succ(rear)
出队时,front=Succ(front);
下面给出方案A的实现:
/*ADT-头文件 AQ_queue.h*/
/**********************************
*author:Felix
*last update:Thu Jan 10 11:53:12 EST 2008
*description:
*
*
*
*/
#ifndef ___AQ_QUEUE___
#define ___AQ_QUEUE___
#include<stdio.h>
#include<stdlib.h>
#ifndef ___AQ_QUEUE_ELEMENT___
#define ___AQ_QUEUE_ELEMENT___
typedef int AQ_Element;
#endif
struct AQ_QueueRecord;
typedef struct AQ_QueueRecord * AQ_Queue;
int AQ_IsEmpty(AQ_Queue q);
int AQ_IsFull(AQ_Queue q);
AQ_Queue AQ_CreateQueue(int MaxElements);
void AQ_DisposeQueue(AQ_Queue q);
void AQ_MakeEmpty(AQ_Queue q);
void AQ_Enqueue(AQ_Element e,AQ_Queue q);
AQ_Element AQ_Front(AQ_Queue q);
void AQ_Dequeue(AQ_Queue q);
AQ_Element AQ_FrontAndDequeue(AQ_Queue q);
#define AQ_MIN_QUEUE_SIZE (5)
#endif
/****实现 文件 AQ_queue.c ****/
/**********************************
*author:Felix
*last update:Thu Jan 10 11:53:12 EST 2008
*description:
*consider define as follows:
* AQ_Queue q;
* It assumes that when q is full ,
* q->front= Succ(q->rear)
*and when empty
* q->front=q->rear
* That is
* if a queue is not empty
* q->front points to the front element
* q->rear points to the next position to insert into
*
*/
#include "AQ_queue.h"
struct AQ_QueueRecord
{
AQ_Element *array;
int capacity;
int front;
int rear;
};
static Succ(int val,AQ_Queue q)
{
return ++val%q->capacity;
}
int AQ_IsEmpty(AQ_Queue q)
{
return q->rear==q->front;
}
int AQ_IsFull(AQ_Queue q)
{
return Succ(q->rear,q)==q->front;
}
AQ_Queue AQ_CreateQueue(int MaxElements)
{
AQ_Queue q;
MaxElements=MaxElements>AQ_MIN_QUEUE_SIZE?MaxElements+1:AQ_MIN_QUEUE_SIZE+1;
q=(AQ_Queue)malloc(sizeof(struct AQ_QueueRecord));
if(q==NULL) return NULL;
q->array=(AQ_Element *)malloc(sizeof(AQ_Element)*MaxElements);
q->capacity=MaxElements;
q->rear=q->front=0;
return q;
}
void AQ_DisposeQueue(AQ_Queue q)
{
free(q->array);
free(q);
}
void AQ_MakeEmpty(AQ_Queue q)
{
q->rear=q->front=0;
}
void AQ_Enqueue(AQ_Element e,AQ_Queue q)
{
if(AQ_IsFull(q))return ;
q->array[q->rear]=e;
q->rear=Succ(q->rear,q);
}
AQ_Element AQ_Front(AQ_Queue q)
{
return q->array[q->front];
}
void AQ_Dequeue(AQ_Queue q)
{
if(AQ_IsEmpty(q))return ;
q->front=Succ(q->front,q);
}
AQ_Element AQ_FrontAndDequeue(AQ_Queue q)
{
AQ_Element e;
e=AQ_Front(q);
AQ_Dequeue(q);
return e;
}
/****测试文件*****/
/***main file for test : testAQ_queue.c*******/
/*///
*author:Felix
*create date:Thu Jan 10 13:32:57 EST 2008
*last update:Thu Jan 10 13:32:57 EST 2008
*description:
*
*
*//
#include "menu_c.h"
#include<stdio.h>
#include<stdlib.h>
#define AQ_TEST_SIZE 5
#include"AQ_queue.h"
int main()
{
AQ_Element e;
AQ_Queue q;
q=AQ_CreateQueue(AQ_TEST_SIZE);
while(SELECT())
{
switch (SELECTION)
{
/*Add an integer to queue.*/
case '1':
printf("integer to input:>");
scanf("%d",&e);
if(AQ_IsFull(q))printf("sorry,it's full now");
else
AQ_Enqueue(e,q);
break;
/*delete the front from queue*/
case '2':
if(AQ_IsEmpty(q))printf("node:no action as it's empty now");
else
AQ_Dequeue(q);
break;
/*show the front*/
case '3':
if(AQ_IsEmpty(q))printf("sorry,it's empty now");
else
printf("%d ",AQ_Front(q));
break;
/*Enqueue and show the fron till the queue is empty*/
case '4':
while(!AQ_IsEmpty(q))printf("%d ",AQ_FrontAndDequeue(q));
break;
case '9':
system("less ../AQ_queue.h");
break;
default:break;
}
}
return 0;
}
/***menu_c.h****/
/*///
*author:Felix
*create date:Thu Jan 10 13:32:57 EST 2008
*last update:Thu Jan 10 13:32:57 EST 2008
*description:
*
*
*/
#include <stdio.h>
#ifndef __MENU____
#define __MENU____
#define SELECT() ((___sel=___select())!='0')
#define SELECTION ___sel
char ___sel;
char ___select();
/*
define the menu:
*/
#endif
/***menu_c.c*****/
/*///
*author:Felix
*create date:Thu Jan 10 13:32:57 EST 2008
*last update:Thu Jan 10 13:32:57 EST 2008
*description:
*
*
*/
#include "menu_c.h"
char *___menu[]={
"1.Add an integer to queue.",
"2.delete the front from queue",
"3.show the front",
"4.Enqueue and show the fron till the queue is empty", "9.Print the file AQ_queue.h",
"0.EXIT",
NULL
};
void ___showMenu()
{
printf("please select:/n");
char **p=___menu;
while(*p)printf("%s/n",*p++);
printf(":>");
}
char ___select()
{
char c;
___showMenu();
while((c=getchar())=='/n');
return c;
}