学习队列 总结

学习队列 总结

队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
结构如下图所示:

队列

队列的抽象数据类型

定义如下:

ADT 队列(Queue)

Data
    同线性表,元素有相同的类型,相邻元素有前驱和后继
Operation
    InitQueue(*Q);
    DestroyQueue(*Q);
    ClearQueue(*Q);
    QueueEmpty(*Q);
    GetHead(Q, *e);
    EnQueue(*Q, e);
    DeQueue(*Q, *e);
    QueueLength(Q);

顺序队列

顺序队列:顺序存储的队列

顺序队列结构体定义

typedef int QElemType;

// 顺序存储的结构(这里是循环队列)
typedef struct
{
    QElemType data[MAXSIZE];
    int front; // 头指针
    int rear; // 尾指针,若队列非空,指向队列尾元素的下一个位置
}SqQueue;

顺序队列的初始化

int InitQueue(SqQueue* pQueue)
{
    pQueue->front = 0;
    pQueue->rear = 0;

    return OK;

}   

入队列

int EnQueue(SqQueue* Queue, QElemType Element)
{
    // 循环队列满的操作
    if (Q->front == (Q->rear + 1) % MAXSIZE)
    {
        return ERROR;
    }
    // 插入元素
    Q->data[Q->rear] = Element;

    Q->rear = (Q->rear + 1) % MAXSIZE;
    return OK;
}

出队列

// 删除队列头元素
int DeQueue(SqQueue* Queue, QElemType* Element)
{
    // 队列判空
    if (Q->front == Q->rear)
    {
        return ERROR;
    }
    // 队列头元素出队列
    *Element = Queue->data[Queue->front];

    Queue->front = (Queue->front + 1) % MAXSIZE;

    return OK;
}

顺序队列置空

int ClearQueue(SqQueue* Queue)
{
    Queue->front = Queue->rear = 0;

    return OK;
}

顺序队列判空

int QueueEmpty(SqQueue Queue)
{
    if (Queue->front == Queue->rear)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

获取队列长度

int QueueLength(SqQueue Queue)
{
    return (Queue->rear - Queue->front + MAXSIZE) % MAXSIZE;
}

链式队列

链式队列大概是下面这样的:

链式队列

当队列为空时, front 和 rear 都指向头结点.

链式队列的结构体定义

typedef int QElemType;
// 链式队列结点结构体定义
typedef struct QNode
{
    QElemType data;
    struct QNode* next;
}QNode, *QueuePtr;

// 链式队列链表结构体定义
typedef struct
{
    QueuePtr front, rear;
}LinkQueue;

链式队列的初始化

int InitQueue(LinkQueue* Queue)
{
    Queue->front = Queue->rear =      (QueuePtr)malloc(sizeof(QNode));
    if (!Queue->front)
        // 异常;

    Queue->front->next = NULL;
    return OK;
}

返回队列头元素

int GetLinkQueueHead(LinkQueue Queue, QElemType* Element)
{
    QueuePtr CurrentQNode;

    // 若为空
    if (Queue->front == Queue->rear)
    {
        return ERROR;
    }

    CurrentQNOde = Queue.front->next;
    *ELement = CurrentQNode->data;
    return OK;
}

链式队列的长度

int LinkQueueLength(LinkQueue Queue)
{
    int num = 0;
    QueuePtr CurrentQNode;
    CurrentQNode = Queue.front;

    while(CurrentQNode != Queue.rear)
    {
        num++;
        CurrentQNode = CurrentQNode->next;
    }

    return num;
}

链式队列判空

int QueueEmpty(LinkQueue Queue)
{
    if(Queue.front == Queue.rear)
    {
        return ERROR;
    }
    else
    {
        return OK;
    }
}

链式队列置空

int ClearLinkQueue(LinkeQueue* Queue)
{
    QueuePtr NewQNode, OldQNode;

    Queue->front = Queue->rear;
    NewQNode = Queue->front->next;
    Queue->front->next = NULL;

    while(NewQNode)
    {
        OldQNode = NewQNode;
        NewQNode = NewQNode->next;
        free(OldQNode);
    }

    return OK;
}

链式队列的销毁

int DestroyLinkQueue(LinkQueue* Queue)
{
    while(Queue->front)
    {
        Queue->rear = Queue->front->next;
        free(Queue->front);
        Queue->front = Queue->rear;
    }
    return OK;
}

入队列操作

int EnQueue(LinkQueue* Queue, QElemType Element)
{
    QueuePtr NewQNode = (QueuePtr)malloc(sizeof(QNode));
    if (NULL == NewQNode)
    {
        //异常;
    }

    NewQNode->data = Element;
    NewQNode->next = NULL;

    Queue->rear->next = NewQNode;
    Queue->rear = NewQNode;

    return OK;
}

出队列操作

int DeQueue(LinkQueue* Queue, QElemType* Element)
{
    QueuePtr CurrentQNode;

    // 判空
    if (Queue->front == Queue->rear)
    {
        // 异常;
    }

    CurrentQNode = Queue->front->next;
    *ELement = CurrentQNode->data;

    Queue->front->next = CurrentQNode->next;
    if (CurrentQNode == Queue->rear)
    {
        Queue->front = Queue->rear;
    }
    free(CurrentQNode);

    return OK;
}

顺序队列与链式队列的比较

用数组实现队列时,如果不移动,随着数据的不断读写,会出现假满队列的情况。即尾数组已满但头数组还是空的。循环队列也是一种数组,只是它在逻辑上把数组的头和尾相连,形成循环队列,当数组尾满的时候,要判断数组头是否为空,不为空继续存放数据,可以有效的利用资源。但是用循环队列有个小麻烦,不好判断数列是为空还是为满;

链队列就不存在上面的问题。“循环队列”最大优点就是节省空间和少分配空间,而链队列多了一点点地址存储开销。

参考文档

http://www.nowamagic.net/librarys/veda/detail/2364

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值