栈和队列(队列及其存储结构)

栈和队列

  • 队列定义:
  • 队列的链式存储结构
    • 创建队列
    • 入队列操作
    • 出队列操作
    • 销毁队列
  • 队列的顺序存储结构
    • 循环队列
    • 代码清单

队列定义:

1、队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
2、与栈相反,队列是一种先进先出的线性表.
3、实现一个队列同样需要顺序表或链表作为基础。

队列的链式存储结构

(队列即可用链表实现,也可以用顺序表实现,而栈一般用顺序表实现,队列用链表实现,简称链队列 )

typedef struct QNode{
    ElemType data;
    struct QNode *next;
    } QNode,*QueuePtr;
typedef struct {
    QueuePtr front,rear;//队头、队尾指针
    }LinkQueue;

(头结点不是必要的,但为了方便操作还是加上)
栈和队列(队列及其存储结构)_第1张图片

空队列时,front和rear都指向头结点。

在这里插入图片描述

创建队列

创建队列要完成两个任务:

一是在内存中创建一个头结点;
二是将队列的头指针和尾指针都指向这个生成的头结点,因此此时是空队列。

initQueue(LinkQueue *q)
{
    q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));
    if( !q->front )
        exit(0);
    q->front->next = NULL;

入队列操作

入队列的操作过程如下:
栈和队列(队列及其存储结构)_第2张图片

InsertQueue(LinkQueue *q,ElemType e)
{
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if( p==NULL)
    exit(0);
p->data = e;
p->next = NULL;
q->rear->next = p;
q->rear = p;
}

出队列操作

出队列操作是将队列中的第一个元素移出,对头指针不发生变化,改变头结点的next指针即可。
栈和队列(队列及其存储结构)_第3张图片

如果原队列只有一个元素,那么就要处理一下队尾指针。
栈和队列(队列及其存储结构)_第4张图片

DeleteQueue(LinkQueue *q, ElemType *e)
{
QueuePtr p;
if( q->front == q->rear)
  return;
p = q->front->next;
*e = p->data;
q->front->next = p->next;
if(q->rear == p)
    q->rear = q->front;
free(p);
}

销毁队列

由于链队列建立在内存动态区,因此当一个队列不再有用时应当把它及时销毁掉,以免过多的占用内存空间

DestroyQueue(LinkQueue *q)
{
while(q->front){
    q->rear = q->front->next;
    free(q->front);
    q->front = q->rear;
    }
}

队列的顺序存储结构

栈和队列(队列及其存储结构)_第5张图片
入队列操作其实就是在队尾追加一个元素,不需要任何移动,时间复杂度为O(1).出队列则不同,因为我们已经架设下标为0的位置是队列的队头,因此每次出队列操作所有元素都要向前移动。
栈和队列(队列及其存储结构)_第6张图片

循环队列

栈和队列(队列及其存储结构)_第7张图片

  • 循环队列的实现只需要灵活的改变front和rear指针即可。

  • 就是让front或rear指针不断+1,即时超出了地位范围,也会自动从头开始。我们可以采取取模运算处理:
    (rear+1)%QueueSize
    (front+1)%QueueSize\

    代码清单

//定义一个循环队列
#define MAXSIZE 100
typedef struct
{
 ElemType *base; //用于存放内存分配基地址
                 //也可以用数组存放
 int front;
 int rearr;
}
//初始化一个队列
initQueue(cycleQueue *q)
{
    q->base = (ElemType *)malloc (MAXSIZE *sizeof(ElemType));
    if( !q->base)
        exit(0);
    q->front = q->rear = 0;
}    
//入队列操作
InsertQueue(cycleQueue *q,ElemType e)
{
    if(q->rear+1)%MAXSIZE == q->front)
        return;//队列已满
    q->base[q->rear] = e;
    q->rear = (q->rear+1)%MAXSIZE;
}
//出队列操作
DeletQueue(cycleQueue *q,ElemType *e)
{
    if(q->front == q->rear)
        return;//队列为空
    *e = q->base[q->front];
    q->front = (q->front+1)%MAXSIZE;
}

你可能感兴趣的:(数据结构)