队列链表实现

队列链表实现

结构声明

图示:链表队列结构模型

对此可做 如下声明

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

typedef struct 
{
    QuenePtr front; /* 队头指针 */
    QuenePtr rear;  /* 队尾指针 */
    int len;
}LinkQuene;

插入元素e到队尾

图示:空队列情况以及往空队列插入元素

图示:队列非空时的插入情况

/* 插入元素e到队尾 */
Status EnQueue(LinkQueue *Q, QElemType e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if(!p)
        return ERROR;
    p->data = e;
    p->next = Q->rear->next;
    Q->rear->next = p;   /* 插入到尾部 */
    Q->rear = p;         /* 插入好后再将尾指针指向p */
    Q->len++;
    return OK;
}

从队头弹出队列元素

图示:将队列元素从队头弹出

图示:只有一个元素的弹出情况

/* 从队头弹出队列元素 */
Status DeQueue(LinkQueue *Q, QElemType *e)
{
    if(Q->front == Q->rear)
        return ERROR;              /* 队列为空 */
    QueuePtr p = Q->front->next;   /* 指向第一个结点 */
    *e = p->data;
    Q->front->next = p->next;      /* 头结点的next指针指向第一个结点的下面 */
    if(Q->rear == p) 
        Q->rear = Q->front;        /* 如果只包含一个结点,删除后需尾指针指向空,需要从指向头结点 */
    free(p);
    Q->len--;
    return OK;
}

完整示例代码

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

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;
typedef int QElemType;

#define STACK_INIT_SIZE 100
#define STACK_INCREMENT 10

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

typedef struct 
{
    QueuePtr front; /* 队头指针 */
    QueuePtr rear;  /* 队尾指针 */
    int len;
}LinkQueue;


/*构造一个空队列 Q */
Status InitQueue(LinkQueue *Q)
{
    Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));   /* 创建头结点 */
    if(!Q->front)
        return ERROR;
    Q->front->next = NULL;  /* 设置头结点指向next指向空 */
    Q->len = 0;             /* 队列个数清零 */
    return OK;
}

/* 插入元素e到队尾 */
Status EnQueue(LinkQueue *Q, QElemType e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if(!p)
        return ERROR;
    p->data = e;
    p->next = Q->rear->next;
    Q->rear->next = p;   /* 插入到尾部 */
    Q->rear = p;         /* 插入好后再将尾指针指向p */
    Q->len++;
    return OK;
}

/* 从队头弹出队列元素 */
Status DeQueue(LinkQueue *Q, QElemType *e)
{
    if(Q->front == Q->rear)
        return ERROR;              /* 队列为空 */
    QueuePtr p = Q->front->next;   /* 指向第一个结点 */
    *e = p->data;
    Q->front->next = p->next;      /* 头结点的next指针指向第一个结点的下面 */
    if(Q->rear == p) 
        Q->rear = Q->front;        /* 如果只包含一个结点,删除后需尾指针指向空,需要从指向头结点 */
    free(p);
    Q->len--;
    return OK;
}

/* 销毁队列 */
Status DestroyQueue(LinkQueue *Q)
{
    /* 直接从头结点开始 */
    while(Q->front) {
        Q->rear = Q->front->next;   /* 让队尾指针指向第一个结点 */
        free(Q->front);             /* 释放当前结点 */
        Q->front = Q->rear;         /* 指向下一个结点 */
    }
    Q->len = 0;
    return OK;
}

/* 检测队列是否为空 */
Status QueueEmpty(LinkQueue *Q)
{
    if(Q->front == Q->rear)
        return TRUE;
    else 
        return FALSE;
}

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

/* 获取队列长度 */
int QueueLength(LinkQueue *Q)
{
    return Q->len;
}

/* 清空队列元素 */
Status ClearQueue(LinkQueue *Q)
{
    if(!Q->front)
        return ERROR;
    
    QueuePtr p = Q->front->next;  /* 指向第一个队列元素 */
    while(p) {                    /* 当前结点非空 */
        Q->rear = p->next;        /* 保存当前结点的下一个结点地址 */
        free(p);                  /* 释放当前结点 */
        p = Q->rear;              /* 指向下一个结点 */
    }
    Q->front->next = NULL;       /* 释放完之后要让头结点指针指向空 */
    Q->rear = Q->front;          /* 尾指针同指向头结点 */
    Q->len = 0;
    return OK;
}

/* 从队头到队尾打印队列 */
void printQueue(LinkQueue * Q)
{
    QueuePtr p = Q->front->next; /* 从第一个结点开始 */
    while(p) {                   /* 当前节点不为空 */
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}

int main()
{
    LinkQueue Queue;
    LinkQueue * Q = &Queue;
    QElemType e;

    // 插入测试 
    InitQueue(Q);
    EnQueue(Q,1);
    EnQueue(Q,2);
    EnQueue(Q,3);
    EnQueue(Q,4);
    printQueue(Q);

    // 获取长度测试 
    printf("len %d\n",QueueLength(Q));

    // 是否为空测试
    printf("empty? %d\n",QueueEmpty(Q));

    // 获取队头测试 
    GetHead(Q,&e);
    printf("head? %d\n",e);

    // 出队列测试
    DeQueue(Q,&e);
    printf("e %d\n",e);
    printQueue(Q);

    // 清空队列测试
    ClearQueue(Q);
    printQueue(Q);

    // 销毁队列测试
    DestroyQueue(Q);
    return 0;
}
posted @ 2019-10-06 09:21  wjundong  阅读(605)  评论(0编辑  收藏  举报