前面贴了一段关于队列的源代码,也许细心的朋友会发现,其实那段代码存在一定的问题。就是最后如果出队后front指向队列尾部的时候;
会出现异常。因此为了能够使用队列,则需要进行修改源代码。
/* * 本程序测试线性数据结构:队列 */ #include <stdio.h> #include <stdlib.h> //***************************************0 // 定义数据类型 struct queueNode { //如果rear ==-1 and front ==-1 则表示队列不存在 //队列不存在不能进行队列的任何操作 int* queue; int front; //队列首 int rear; //队列尾 int maxSize; }; typedef struct queueNode QUEUE; typedef QUEUE* PQUEUE; typedef enum {FALSE,TRUE} BOOL; //***************************************1 //***************************************0 // 定义用户常量 #define MAX_QUEUE_SIZE 4 //***************************************1 //***************************************0 PQUEUE createQueue(void); BOOL initQueue(PQUEUE queue); BOOL isEmpty(PQUEUE queue); BOOL isFull(PQUEUE queue); BOOL enqueue(PQUEUE queue,int element); BOOL dequeue(PQUEUE queue,int* element); int main(void) { PQUEUE queue; int x; queue=createQueue(); if(initQueue(queue)) puts("yes"); if(isEmpty(queue)) puts("yes"); if(enqueue(queue,1)) puts("En success"); if(enqueue(queue,1)) puts("En success"); if(enqueue(queue,1)) puts("En success"); if(enqueue(queue,1)) puts("En success"); //这样应该输出三个En success if(isFull(queue)) puts("yes"); if(dequeue(queue,&x)) printf("dequeue success,%d\n",x); if(enqueue(queue,1)) puts("En success"); getchar(); getchar(); return 0; } //***************************************1 //***************************************0 /* 函数功能: 创建队列 函数原型: PQUEUE createQueue(void) 函数参数: 无 返回值: 如果创建成功,则返回队列存储地址,否则返回空 异常: 无 */ PQUEUE createQueue(void) { PQUEUE queue; queue=malloc(sizeof(QUEUE)); if(queue) { queue->front=-1; queue->rear=-1; return queue; } else { return NULL; } } //***************************************1 //***************************************0 /* 函数功能: 初始化队列 函数原型: BOOL initQueue(PQUEUE queue) 函数参数: PQUEUE queue:待初始化队列 返回值: 如果初始化成功,则返回TRUE;否则返回FALSE 异常: 无 */ BOOL initQueue(PQUEUE queue) { if(!queue) return FALSE; queue->queue=malloc(sizeof(int)*MAX_QUEUE_SIZE); if(queue) { queue->front=-1; queue->rear=0; queue->maxSize=MAX_QUEUE_SIZE; return TRUE; } else { return FALSE; } } //***************************************1 //***************************************0 /* 函数功能: 判断队列是否为空 函数原型: BOOL isEmpty(PQUEUE queue) 函数参数: PQUEUE queue:队列指针 函数返回值: 如果为空,返回TRUE;否则返回FALSE 异常: 无 */ BOOL isEmpty(PQUEUE queue) { if(!queue ||queue->rear== -1 ) { puts("Error."); exit(0); } return queue->rear==0?TRUE:FALSE; } //***************************************1 //***************************************0 /* 函数功能: 判断队列是否为满 函数原型: BOOL isFull(PQUEUE queue) 函数参数: PQUEUE queue:队列指针 函数返回值: 如果为满,返回TRUE;否则返回FALSE 异常: 无 */ BOOL isFull(PQUEUE queue) { if(!queue || queue->rear == -1) { puts("Error."); exit(0); } if(-1==queue->front &&queue->rear==(queue->maxSize - 1)) return TRUE; else return FALSE; } //***************************************0 //***************************************0 /* 函数功能: 移动队列的元素,将front置为-1; 函数原型: void moveQueue(PQUEUE queue) 函数参数: PQUEUE queue:队列 返回值: 无 异常: 无 */ void moveQueue(PQUEUE queue) { int i, j; //这个函数仅在入队函数中使用,有效性在入队函数已经进行完 i=queue->front ; queue->front =-1; j=0; while(j<i) { queue->queue[j]=queue->queue[i+j]; j++; } queue->rear =queue->maxSize - queue->front ; } //***************************************1 //***************************************0 /* 函数功能: 入队 函数原型: BOOL enqueue(PQUEUE queue,int element) 函数参数: PQUEUE queue:队列 int element:要入队的元素 返回值: 入队成功,返回TRUE;否则返回FALSE; 异常: 无 */ BOOL enqueue(PQUEUE queue,int element) { if(!queue || queue->rear == -1) { puts("Error."); exit(0); } if(isFull(queue)) return FALSE; else { /* 这个地方也可以用这样的逻辑,更简洁 if(queue->rear==queue->maxSize -1) moveQueue(queue); queue->queue[queue->rear++]=element; return TRUE; */ if(queue->rear!=queue->maxSize -1) { //如果尾rear没有到最后,则直接增加 queue->queue[queue->rear++]=element; return TRUE; } else { //如果rear到了最后,且没有满队列,则需要移动元素 //移动完后,在增加元素 moveQueue(queue); queue->queue[queue->rear++]=element; return TRUE; } } } //***************************************1 //***************************************0 /* 函数功能: 出队 函数原型: BOOL dequeue(PQUEUE queue,int* element) 函数参数: PQUEUE queue:队列 int* element:存储出队后的元素 返回值: 如果出队成功,则返回TRUE,并设置 *element=队首元素 如果出队失败,则返回FALSE,并设置 *element=0 异常: 无 */ BOOL dequeue(PQUEUE queue,int* element) { if(!queue || queue->rear == -1) { puts("Error."); exit(0); } if(isEmpty(queue)) return FALSE; *element= queue->queue[++queue->front]; return TRUE; } //***************************************0
代码运行结果如下所示:
如果用循环队列的话,就不会存在上面的问题.