3.2 队列-链式存储
// 带头节点的链式存储队列 #include <stdio.h> #include <stdlib.h> typedef struct node{ int data; struct node * next; }QNode; typedef struct queue{ QNode *front; QNode *rear; }Queue; void initQueue(Queue *Q){ Q->front=Q->rear=(QNode *)malloc(sizeof(QNode)); Q->front->next=NULL; } int isEmpty(Queue * Q){ return Q->rear == Q->front; } // 入队使用尾插法好一些,出队front+1,入队rear+1,和书上保持一致 int enQueue(Queue * Q,int e){ QNode * p = (QNode *)malloc(sizeof(QNode)); if(p==NULL) return 0; // 分配失败 p->data = e; p->next = NULL; Q->rear->next = p; Q->rear = p; // 入队更新rear,指向新节点 return 1; } int deQueue(Queue * Q,int *e){ QNode *p; if(isEmpty(Q)){ puts("Empty!"); return 0; } p=Q->front->next; *e=p->data; Q->front->next=p->next; // 注意这里,带头节点 if(Q->rear==p) Q->rear=Q->front; // 如果要被释放的p节点是除头节点的唯一节点 free(p); return 1; //直接返回,取地址的话会出现问题 } void Traverse(Queue *Q){ QNode *p; p=Q->front->next; while(p!=NULL){ printf("%d ",p->data); p=p->next; } printf("\n"); } // 连同头节点也被销毁掉了 void destroyQueue(Queue *Q){ while(Q->front!=NULL){ Q->rear=Q->front->next; free(Q->front); Q->front=Q->rear; } printf("Destroyed!\n"); } int main(){ Queue Q; initQueue(&Q); int i,e; for(i=1; i<=10; i++){ enQueue(&Q,i); } deQueue(&Q,&e); printf("DQ:%d \n",e); deQueue(&Q,&e); printf("DQ:%d \n",e); deQueue(&Q,&e); printf("DQ:%d \n",e); Traverse(&Q); destroyQueue(&Q); return 0; }
// 不带头节点的链式存储队列 #include <stdio.h> #include <stdlib.h> typedef struct node{ int data; struct node * next; }QNode; typedef struct queue{ QNode *front; QNode *rear; }Queue; void initQueue(Queue *Q){ Q->front=Q->rear=NULL; // 带头节点版本在这里分配头节点 } int isEmpty(Queue * Q){ return Q->front == NULL; // front==rear的时候可能为空可能为唯一节点 } // front或rear为空则一定为空 // 入队使用尾插法好一些,出队front+1,入队rear+1,和书上保持一致 int enQueue(Queue * Q,int e){ QNode * p = (QNode *)malloc(sizeof(QNode)); // 分配存储节点 if(p==NULL) return 0; // 分配失败 p->data = e; p->next = NULL; if(isEmpty(Q)){ // 不带头节点版本要判空,第一个元素特殊处理 Q->rear = p; Q->front= p; // Q为空的时候p为首节点 } else { Q->rear->next=p; // 尾插新节点,入队 Q->rear=Q->rear->next; // 特别注意这里,还要更新尾指针 } return 1; } // 左边front,右边rear int deQueue(Queue * Q,int *e){ QNode *p; if(isEmpty(Q)){ puts("Empty!"); return 0; } p=Q->front; *e=p->data; Q->front=p->next; // 注意这里,不带头节点 if(Q->rear==Q->front) Q->rear=Q->front=NULL; // 如果要被释放的p节点是除头节点的唯一节点 free(p); return 1; } void Traverse(Queue *Q){ QNode *p; p=Q->front; while(p!=NULL){ printf("%d ",p->data); p=p->next; } printf("\n"); } // 和带头节点的相同 void destroyQueue(Queue *Q){ while(Q->front!=NULL){ Q->rear=Q->front->next; free(Q->front); Q->front=Q->rear; } printf("Destroyed!\n"); } int main(){ Queue Q; initQueue(&Q); int i,e; for(i=1; i<=10; i++){ enQueue(&Q,i); } Traverse(&Q); deQueue(&Q,&e); printf("DQ:%d \n",e); deQueue(&Q,&e); printf("DQ:%d \n",e); deQueue(&Q,&e); printf("DQ:%d \n",e); Traverse(&Q); destroyQueue(&Q); return 0; }