链队列的基础操作:
链队列有头结点,
初始化的时候要给头结点和尾结点开辟空间
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define OK 1
#define ERROR -1
#define OVERFLOW -2
typedef int QElemType;
typedef int Status;
//先定义结点结构体
typedef struct QNode
{
QElemType data;
struct QNode* next;
}QNode,*QueuePtr;
//定义链队列结构体
typedef struct
{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
//初始化一个空的链队列
//给首尾指针首先要开辟一个空间,这个链表是有头的
Status InitQueue(LinkQueue &Q)
{
Q.rear=Q.front=(QueuePtr)malloc(sizeof(QNode));
if(!Q.rear)
exit(OVERFLOW);
Q.rear->next=NULL;//记得要把
return OK;
}
//添加结点,每次都开辟空间制造结点,更新rear
Status EnQueue(LinkQueue &Q,QElemType e)
{
QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
//队头出队
Status DeQueue(LinkQueue &Q,QElemType &e)
{
if(Q.rear==Q.front)
return ERROR;
QueuePtr p=Q.front->next;
e=p->data;
Q.front->next=p->next;
//因为在判断队列是否是空的时候只看rear和front
//所以当让rear出队的时候,一定要让rear==front
if(p==Q.rear)
Q.rear=Q.front;
free(q);
q=NULL;
return OK;
}
//求队列的长度
//只要指针到不了最后一个,就一直向后移,每移一位加一
int GetLength(LinkQueue Q)
{
int cnt=0;
while(Q.front!=Q.rear)
{
cnt++;
Q.front=Q.front->next
}
return cnt;
}
//销毁队列,不保留头结点
Status DestroyQueue (LinkQueue &Q)
{
//快慢指针,
Q.rear=Q.front->next;
while(Q.front)
{
free(Q.front);
Q.front=Q.rear;
Q.rear=Q.front->next;
}
return OK;
}
//清空队列
//保留头结点,还是使用快慢指针
Status ClearQueue(LinkQueue &Q)
{
Q.rear=Q.front->next->next;
while(Q.front->next)
{
free(Q.front->next);
Q.front->next=Q.rear;
Q.rear=Q.rear->next;
}
Q.rear=Q.front;
}
循环队列
注意判断是否满了不是整个数组都满了,而是rear到了front前面
rear前进的方式(rear+1)%MAXSIZE
#include<bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR -1
#define OVERFLOW -2
#define MAXQSIZE 100
typedef int QElemtype;
typedef int Status;
typedef struct
{
QElemtype *base;
int front;
int rear;
}SqQueue;
/*初始化队列*/
Status Init_Queue(SqQueue &Q)
{
Q.base=(QElemtype*)malloc(sizeof(QElemtype)*MAXQSIZE);
if(!Q.base)
exit(OVERFLOW);
Q.front=Q.rear=0;
return OK;
}
/*入队*/
Status EnQueue(SqQueue &Q,QElemtype e)
{
if((Q.rear+1)%MAXQSIZE==Q.front)
return ERROR;//如果循环队列已满就返回错误
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
}
/*出队*/ //要记得是在front出队
Status DeQueue(SqQueue &Q,QElemtype &e)
{
if(Q.front==Q.rear)
return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
/*销毁*///
Status DestroyQueue(SqQueue &Q)
{
free(Q.base);
Q.front=Q.rear=0;
return OK;
}
/*清空队列*/
Status ClearQueue(SqQueue &Q)
{
Q.rear=Q.front;
return OK;
}
/*求队列的长度*/
//要记住rear的位置是队列末尾最后一个元素后面的第一个位置
//不存数据是为了便于求长度,和栈的top差不多
//MAXSIZE-1的时候就判定为满了
/*求队列的长度*/
int GetLength(SqQueue &Q)
{
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
/*判断队列是否为空*/
Status isEmpty(SqQueue Q)
{
return Q.front==Q.rear?1:0;
}
Status TraverseQueue(SqQueue Q)
{
for(int i=Q.front;i!=Q.rear;i=(i+1)%MAXQSIZE)
{
cout<<Q.base[i];
}
}