队列的两种实现方式

318 阅读3分钟
  1. 顺序存储模式的队列

Q.front 指向目前队列中的第一个元素。

Q.rear 指向队列中下一个新元素要插入的位置。

为了合理管理应用队列的空间,防止混淆队列队空和对满的情况,我们会特意空出队列中的一个空间。这个空出来的空间不是固定的会随着情况变动 队空的条件

判断队空:Q.front == Q.rear;

判断队满:(Q.rear + 1)%MAXSIZE == Q.front

#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 //存储空间初始分配量

typedef int Status;
typedef int QElemType;

//顺序存储结构的队列
typedef struct {
  //1.开辟连续空间存储队列数据内容
    QElemType data[MAXSIZE];
  //2. 索引
    int front; // 队头
    int rear;  // 队尾
}SqQueue;

//1. 初始化空队列
Status InitQueue(SqQueue *Q){
    Q->front = 0;
    Q->rear = 0;
    return OK;
}

//2. 队列的清空
Status ClearQueue(SqQueue *Q) {
    Q->front = Q->rear = 0;
    return OK;
}

//3. 判断队列是否为空
Status iSQueueEmpty(SqQueue Q) {
    if(Q.front == Q.rear) return TRUE;
    return FALSE;
}

//4. 队列的长度
int QueueLength(SqQueue Q) {
    return (Q.rear - Q.front + MAXSIZE)%MAXSIZE;
}

//5. 获取队头元素
Status GetHead(SqQueue Q, QElemType *e) {
    // 判断队是否为空
    if (Q.front == Q.rear) return FALSE;
    // 若队不为空则返回队头元素
    *e = Q.data[Q.front];
    return OK;
}

//6. 入队
Status EnQueue(SqQueue *Q, QElemType e) {
    if((Q->rear + 1)%MAXSIZE == Q->front) return ERROR;
    Q->data[Q->rear] = e;
    Q->rear = (Q->rear + 1)%MAXSIZE;
    return OK;
}

//7. 出队
Status DeQueue(SqQueue *Q, QElemType *e) {
    if(Q->front == Q->rear) return ERROR;
    *e = Q->data[Q->front];
    Q->front = (Q->front + 1)%MAXSIZE;
    return OK;
}

//8. 遍历
Status QueueTraverse(SqQueue Q){
    int i = Q.front;
    while (i!= Q.rear) {
        printf(" %d ", Q.data[i]);
        i = (i+1)%MAXSIZE;
    }
    printf("\n");
    printf("Queue print over \n");
    return OK;
}
  1. 链式存储模式的队列

Q.front 指向头结点即可,不用在挪动,注意是头结点,不是首元结点。

#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 //存储空间初始分配量

typedef int Status;
typedef int QElemType;

typedef struct QNode{
    QElemType data;
    struct QNode *next;
}QNode, *QueuePtr;

// 链表结构的队列
typedef struct {
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

//1.链式队列初始化
Status InitQueue(LinkQueue *Q){
    Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
    if(!Q->front && !Q->rear) return ERROR;
    Q->front->next = NULL;
    
    return OK;
}

//2. 销毁队列
Status DestoryQueue(LinkQueue *Q) {
    while (Q->front) {
        Q->rear = Q->front->next;
        free(Q->front);
        Q->front = Q->rear;
    }
    
    return OK;
}

//3. 清空队列
Status ClearQueue(LinkQueue *Q) {
    QueuePtr p, q;
    Q->rear = Q->front;
    p = Q->front->next;
    Q->front->next = NULL;
    while (p) {
        q = p;
        p = p->next;
        free(q);
    }
    
    return OK;
}

//4. 判断队列是否为空
Status iSQueueEmpty(LinkQueue Q){
    if(Q.front == Q.rear) return TRUE;
    return FALSE;
}

//5. 判断队列的长度
int QueueLength(LinkQueue Q) {
    int i = 0;
    QueuePtr p;
    p = Q.front;
    while (Q.rear != p) {
        i++;
        p = p->next;
    }
    
    return i;
}

//6. 插入元素
Status EnQueue(LinkQueue *Q, QElemType e){
    // 新节点
    QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
    if(!s) return ERROR;
    
    //赋值
    s->data = e;
    s->next = NULL;
    
    //将新节点接入链表队列
    Q->rear->next = s;
    Q->rear = s;
    
    return OK;
}

//7. 出队
Status DeQueue(LinkQueue *Q, QElemType *e){
    
    if (Q->front == Q->rear) return ERROR;
    
    QueuePtr p;
    p = Q->front->next;
    
    Q->front->next = p->next;
    if(Q->rear == p) Q->rear = Q->front;
    free(p);
    
    return  OK;
}

//8.获取队头元素
Status GetHead(LinkQueue Q, QElemType *e){
    if(Q.front != Q.rear){
        *e = Q.front->next->data;
        return TRUE;
    }
    return FALSE;
}

//9. 遍历链表队列
Status QueueTraverse(LinkQueue Q){
    QueuePtr p;
    p = Q.front->next;
    while (p) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
    return OK;
}