顺序队列的基本算法及循环队列

来源:互联网 发布:java上传压缩包并解压 编辑:程序博客网 时间:2024/06/13 22:39

队列的顺序存储结构类型描述如下:

#define M 1000QElemType queue[ M ];int front, rear;

队头指针front指出实际队头元素所在位置的前一个位置,而队尾指针rear指出实际队尾元素所在的位置,初始时,队列为空有front = rear = -1, 测试一个队列是否为空的条件是front = rear.

顺序队列的基本算法如下:

/* 顺序队列的基本算法 */#include<stdlib.h>#include<stdio.h>/* 队列的顺序存储结构类型 */#define M 1000/* 初始化一个队列 */void initialQ( int *front, int *rear ){*front = -1;*rear = -1;}/* 测试队列是否为空 */int isEmpty( int front, int rear ){return front == rear;}/* 取当前队头元素 */int getQ( int queue[  ], int front, int rear, int *item ){if( isEmpty( front, rear ) )   /* 如队列为空,操作失败,返回0 */return 0;else{                         /* 取出对头元素,操作成功,返回1 */*item = queue[ front+1 ];return 1;}}/* 队列的插入,入队 */int addQ( int queue[  ], int *rear, int item ){if( *rear == M-1 )return 0;       /* 队列已满,插入失败,返回0 */else{queue[ ++( *rear ) ] = item;return 1;         /* 队列未满,插入成功,返回1 */}}/* 队列的删除,出队 */int deleteQ( int queue[  ], int *front, int rear, int *item ){if( isEmpty( *front, rear ) )   /* 队列为空,删除失败,返回0 */return 0;else{*item = queue[ ++( *front ) ];  /* 保存队头元素,队列头指针后移1 */return 1;}}void printQ( int queue[  ], int front, int rear ){int p;printf( "the elem in queue is:" );for( p = front + 1; p <= rear; p++ ){printf( "%3d", queue[ p ] );}}int main(){int queue[ M ];int front, rear;initialQ( &front, &rear );printf( "the queue is empty %d\n", isEmpty( front, rear ) );addQ( queue, &rear, 8 );addQ( queue, &rear, 14 );addQ( queue, &rear, 84 );printQ( queue, front, rear );int elem;deleteQ( queue, &front, rear, &elem );printf( "the deleted elem is%d\n", elem );getQ( queue, front, rear, &elem );printf( "the front elem is %d\n", elem );return 0;}

为了节省存储空间,可使用循环队列,初始化循环队列时令front = rear = 0, 并且把队列设想成头尾相连的循环表,使得空间得以重复使用,在进行插入操作时,当队列的第M个位置(数组下标是M-1)被占用后,只要队列前面还有可用空间,新的元素加入队列时就可以从第1个元素(数组下标为0)开始,按照这种思路,插入算法中修改队尾指针的语句可以写成:

if(rear == M-1)    rear = 0;else    rear ++;

若修改后的队尾指针满足rear = front,那么真的要产生溢出了,上述语句可用求模运算改写成:

rear = (rear + 1) % M;

在删除算法中也可以有:

front = (front + 1) % M;

循环队列的插入和删除算法如下:

/* 循环队列的插入 */int addCQ( int queue[  ], int front, int *rear, int item ){if( (*rear + 1)%M == front )  /* 循环队列已满,插入失败,返回0 */return 0;else{queue[ ++(*rear)%M ] = item;  /* 循环队列未满,插入成功,返回1 */return 1;}}/* 循环队列的删除 */int deleteCQ( int queue[  ], int *front, int rear, int *item ){if( *front == rear )        /* 循环队列为空,删除失败,返回0 */return 0;else{*front = (*front + 1)%M;   /* 删除并保存头结点元素 */*item = queue[ *front ];return 1;}}

只有当rear 加1 以后从“后面”赶上来并等于front是才是循环队列“满”的情况,其余情况下的front等于rear均表示循环队列为空,应说明一点的是,此时循环队列的“满”,实际上还有一个空位置(仅一个), 用来区分“上溢” 和 “下溢”,头指针所指位置为空位置,不存元素。