队列基本操作

 

链式存储
typedef int QElemType;
typedef int Status;//具体数据类型具体定义
typedef struct QNode//队列结点结构体
{
    QElemType data;
    QNode *next;
} QNode, *Queueptr;

typedef struct   // 链队列类型
{
    Queueptr  front;  // 队头指针(结构体类型的指针)等价于 QNode *front;
    Queueptr  rear;   // 队尾指针
} LinkQueue;

Status InitQueue (LinkQueue &Q) // 构造一个空队列Q
{
    Q.front = Q.rear = (Queueptr)malloc(sizeof(QNode));
    if (!Q.front) exit (0); //存储分配失败
    Q.front->next = NULL;
    return 1;
}

Status EnQueue (LinkQueue &Q, QElemType e)// 插入元素e为Q的新的队尾元素
{
    p = (Queueptr) malloc (sizeof (QNode));
    if (!p)  exit (0);   //存储分配失败
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;//类似于顺序建立链表的过程
    return 1;
}

Status DeQueue (LinkQueue &Q,   QElemType &e)//若队列不空,则删除Q的队头元素,用 e 返回其值
{
    if (Q.front == Q.rear)  //若队空
        return 0;
    p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;//删除操作
    if (Q.rear == p)//如果是最后一个元素
        Q.rear = Q.front;//删除即队空
    free (p);
    return 1;
}

Status GetHead(LinkQueue Q,QElemType &e)// 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
{
    Queueptr p;
    if(Q.front==Q.rear)//队空
        return 0;
    p=Q.front->next;//取队首元素
    e=p->data;
    return 1;
}


Status QueueEmpty(LinkQueue Q)  // 若Q为空队列,则返回1,否则返回0
{
    if(Q.front==Q.rear)
        return 1;
    else
        return 0;
}


void ClearQueue(LinkQueue &Q) // 将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);
    }
}

Status DestroyQueue(LinkQueue  &Q)//销毁队列
{
    while(Q.front)
    {
        Q.rear=Q.front->next;//Q.rear指向当前删除结点下一结点
        free(Q.front);
        Q.front=Q.rear; //Q.front指向当前删除结点(队头元素)
        //释放一块内存要做两点:1.释放指向它的指针。2.将该指针指向空
    }
    return 1;
}

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

 

顺序存储(循环队列--解决假溢出问题)

1. 头指针指向队首元素,尾指针指向队尾的下一个位置。(这里的指针可认为是数组下标)
 
2. 为了区分队满与队空,则定义一个存储空间为MAXQSIZE大小的队列只允许存放(MAXQSIZE-1)个数据。
 
3. 判空条件为:if(Q.front == Q.rear) return true;
 
   判满条件为:if((Q.rear+1) % MAXQSIZE==Q.front) return true;
 
4. 循环队列的长度为:(Q.read-Q.front + MAXQSIZE) % MAXQSIZE
 
5. 当删除对头元素或者在对尾插入元素时指针均需向后移动:
  
    (1). Q.rear=(Q.rear+1) % MAXQSIZE;
    (2). Q.front=(Q.front+1) % MAXQSIZE;
   

InitQueue(&Q)//构造一个空队列Q
GetHead(Q, &e)//获取队头元素
EnQueue(&Q, e)//插入队尾元素
DeQueue(&Q, &e)//删除队头元素
DestroyQueue(&Q)//销毁队列
ClearQueue(&Q)//清空队列
QueueEmpty(Q)//判断队列是否为空
QueueLength(Q)//求当前队列长度

 

#define MAXQSIZE  100  //最大队列长度
typedef int QElemType;
typedef int Status;//具体数据类型具体定义
typedef struct
{
    QElemType  *base;  // 初始化的动态分配存储空间
    int  front;  // 头指针,若队列不空,指向队列头元素
    int  rear;  // 尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;

Status InitQueue (SqQueue &Q) // 构造一个空队列Q
{
    Q.base = (ElemType *) malloc (MAXQSIZE *sizeof (ElemType));
    if (!Q.base) exit (0);// 存储分配失败
    Q.front = Q.rear = 0;
    return 1;
}


Status EnQueue(SqQueue &Q, ElemType e)// 插入元素e为Q的新的队尾元素
{
    if ((Q.rear+1) % MAXQSIZE == Q.front)//队列满
        return 0;
    Q.base[Q.rear] = e;//插入队尾元素
    Q.rear = (Q.rear+1) % MAXQSIZE;//尾指针向后移动
    return 1;
}

Status DeQueue (SqQueue &Q, ElemType &e)  // 若队列不空,则删除Q的队头元素,用e返回其值
{
    if (Q.front == Q.rear)  return 0;
    e = Q.base[Q.front];//队首元素
    Q.front = (Q.front+1) % MAXQSIZE;//头指针向后移动
    return 1;
}

Status GetHead (SqQueue &Q, ElemType &e)//取队首元素
{
    if (Q.front == Q.rear)  return 0;
    e = Q.base[Q.front];//队首元素
    return 1;
}
Status QueueEmpty (SqQueue &Q)//判断队是否为空
{
    if (Q.front == Q.rear)
        return 1;
    else
        return 0;
}

void ClearQueue(SqQueue &Q)// 将Q清为空队列
{
    Q.front=Q.rear=0;
}

void DestroyQueue(SqQueue &Q)// 销毁队列Q,Q不再存在
{
    if(Q.base)
        free(Q.base);
    Q.base=NULL;
    Q.front=Q.rear=0;
}

int QueueLength(SqQueue Q)  // 返回Q的元素个数,即队列的长度
{
    return(Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值