数据结构:队列的链式存储结构

链队列的实现方法:


队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,简称为链队列。
为了操作上的方便,我们将队头指针指向链队列的头节点,而队尾指针指向终端节点。空队列时,front和rear都指向头节点。

注意:这里的实现是有头结点的,在队列的初始化函数中要为头结点开辟空间。

链队列的实现代码:


#include <iostream>
#include <stdlib.h>
using namespace std;

/*******************************
*
*    链队列的结构实现
*
*******************************/
typedef int QElemType;
typedef struct QNode
{
    QElemType data;
    struct QNode *next;
}QNode, *QNodePtr;

typedef struct
{
    QNodePtr front;
    QNodePtr rear;
}LinkQueue;


/*******************************
*
*    链队列的操作实现
*
*******************************/

/*初始化一个链队列*/
bool InitQueue(LinkQueue *lq)
{
    cout << "Init LinkQueue ..." << endl;
    
    QNodePtr p = (QNodePtr)malloc(sizeof(QNode));
    p->next = NULL;
    lq->front = lq->rear = p;

    return true;
}

/*插入元素e为Q的新的队尾元素*/ 
bool EnQueue(LinkQueue *lq, QElemType e)
{
    QNodePtr s = (QNodePtr)malloc(sizeof(QNode));
    if(!s)
    {
        exit(0);
    }
    s->data = e;
    s->next = NULL;

    lq->rear->next = s;
    lq->rear = s;

    return true;
}
/*删除队列的队头元素,用e返回其值*/
bool DeQueue(LinkQueue *lq, QElemType *e)
{
    QNodePtr p = NULL;

    if(lq->front == lq->rear)
    {
        return false;
    }
    p = lq->front->next;

    *e = p->data;

    lq->front->next = p->next;

    if(p == lq->rear)/*若队头同时又是队尾,则删除后将rear指向头结点*/
    {
        lq->rear = lq->front;
    }
    cout << "DeQueue Item: " << *e << endl;
    free(p);

    return true;
}
/*销毁队列,包括头结点*/
bool DestroyQueue(LinkQueue *lq)
{
    cout << "Destroy Queue... " << endl;
    while(lq->front)
    {
        lq->rear = lq->front->next;
        free(lq->front);
        lq->front = lq->rear;
    }

    return true;
}
/*将队列清空,但是保留头结点*/
bool ClearQueue(LinkQueue *lq)
{
    if(lq->front == lq->rear)
    {
        return true;
    }
    cout << "Clear Queue ..." << endl;
    QNodePtr p = lq->front->next;
    QNodePtr q = NULL;

    lq->front->next = NULL;
    lq->rear = lq->front;

    while(p)
    {
        q = p->next;
        free(p);
        p = q;
    }

    return true;
}
/*判断队列是否为空*/
bool IsEmptyQueue(LinkQueue lq)
{
    return lq.front == lq.rear;
}

/*返回队列中结点的个数*/
int QueueLength(LinkQueue lq)
{
    int count = 0;
    if(lq.front == NULL)//队列没有初始化
    {
        return 0;
    }
    QNodePtr p = lq.front->next;
    while(p)
    {
        p = p->next;
        count++;
    }

    return count;
}
/*返回队列的队头元素*/
bool GetTop(LinkQueue *lq, QElemType *e)
{
    QNodePtr p;
    if(lq->front == lq->rear)
    {
        return false;
    }
    p = lq->front->next;
    *e = p->data;

    cout << "Get Top Item: " << *e << endl;

    return true;
}

/*遍历队列中的各个元素*/
bool QueueTraverse(LinkQueue lq)
{
    if(lq.front == lq.rear)
    {
        return false;
    }
    cout << "Queue Traverse ..." << endl;
    QNodePtr p = lq.front->next;

    while(p)
    {
        cout << p->data <<' ';
        p = p->next;
    }
    cout << endl;

    return true;
}

void main(void)
{
    LinkQueue lq;
    InitQueue(&lq);
    for(int i = 0; i < 5; i++)
    {
        EnQueue(&lq, i);
    }

    QueueTraverse(lq);
    int result;
    GetTop(&lq, &result);
    DeQueue(&lq, &result);
    if(!IsEmptyQueue(lq))
    {
        cout << "Queue Length: " << QueueLength(lq) << endl;
    }
    QueueTraverse(lq);
    DestroyQueue(&lq);

    system("pause");
}

执行结果:

image

总的来说,在可以确定队列长度最大值的情况下,建议使用循环队列;如果无法预估队列的长度时,则用链队列。

posted @ 2015-02-10 16:34  stemon  阅读(615)  评论(0编辑  收藏  举报