持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情
1、队列
队列和栈一样是特殊的线性表,它只允许队尾插入,队首删除。就和问我们在窗口排队一样,先来后到。所以很明显,队列可以用解决类似于排队这类问题。
2、顺序存储结构
#define MAXSIZE 100//最大容量
typedef int DataType;//可以是自定义数据类型
typedef struct
{
DataType Data[MAXSIZE];//队列的存储空间
int front, rear;//队头与队尾指针,front rear 是下标。
}SeqQueue,*PSeqQueue;
1、队列初始化
PSeqQueue Init_SeqQueue()
{//初始化一个新队列,入口参数:无 ,返回值:新顺序队列指针,null表示失败
PSeqQueue Q;
Q = (PSeqQueue)malloc(sizeof(SeqQueue));//在堆区开辟空间
if (Q)
{
Q->front = 0;//初始为空对
Q->rear = 0;//初始为空对
}
return Q;//创建成功
}
2、判队空
int Empty_SeQueue(PSeqQueue Q)
{
if (Q&&Q->front == Q->rear)
return 1;//队列为空
else
if (!Q) return -1;//队列不存在
else
return 0;//队列非空
}
3、入队
int In_SeqQueue(PSeqQueue Q,DataType x)//入队元素是DataType x
{
if ((Q->rear + 1) % MAXSIZE == Q->front)//判断队满
{
printf("队满!");
return -1;//队满不能入队
}
else
{
Q->rear = (Q->rear + 1) % MAXSIZE;//干嘛取余啊???跟没取一样
Q->Data[Q->rear] = x;//Q->front位置没有使用
return 1;//入队完成
}
}
4、出队
int Out_SeqQueue(PSeqQueue Q, DataType *x)
{
if (Empty_SeQueue(Q))
{
printf("队空!");
return - 1;//队空,不能出队
}
else
{
Q->front = (Q->front + 1) % MAXSIZE;//Q->front 后移,原位置出队
*x = Q->Data[Q->front];//x等于队头元素
return 1;//出队成功
}
}
5、读队头元素
int Front_SeqQueue(PSeqQueue Q, DataType *x)
{
if (Empty_SeQueue(Q))
{
printf("队空!");
return -1;//队空,不能得到队头元素
}
else
{
*x = Q->Data[(Q->front + 1) % MAXSIZE];//front rear 用来控制下标
return 1;//取对头元素完成
}
}
销毁队列
void Destory_SeqQueue(PSeqQueue *Q)//地址传递
{
if (*Q)//释放一次队列
free(*Q);
*Q = NULL;//释放一次临时的PSeqQueue变量
}
2、队列的链表存储方式
typedef struct node//节点的结构
{
DataType Data;
struct node* next;
}Qnode,*PQNode;
//队头队尾指针
typedef struct
{
PQNode front, rear;
}LinkQueue,*PLinkQueue;
1、初始化队列
PLinkQueue Init_LinkQueue()
{
PLinkQueue Q;
Q = (PLinkQueue)malloc(sizeof(LinkQueue));
if (Q)
{
Q->front = NULL;
Q->rear = NULL;//顺序存储这里是令其等于0
}
return Q;
}
2、判队空
int Empty_LinkQueue(PLinkQueue Q)
{
if (Q&&Q->front == NULL && Q->rear == NULL)
return 1;
else
return 0;
}
3、入队
PSeqQueue In_LinkQueue(PLinkQueue Q,DataType x)
{
PQNode p;//节点
p = (PQNode)malloc(sizeof(Qnode));
if (!p)
{
printf("内存溢出");
return 0;
}
p->Data = x;
p->next = NULL;
if (Empty_LinkQueue(Q))//如果为空,入队的是第一个元素,要担任来连接front和rear的责任
{
Q->rear = Q->front = p;//和顺序存储不同,这个对头存储了数据
}
else//入队的不是第一个元素,将其挂在rear上,rear后移
{
Q->rear->next = p;
Q->rear = p;
}
return 1;
}
4、出队
int Out_LinkQueue(PLinkQueue Q,DataType *x)
{
PQNode p;
if (Empty_LinkQueue(Q))//如果为空
{
printf("队空!");
return 0;//队空不能出队
}
else
{
*x = Q->front->Data;//和顺序存储不同,这个对头存储了数据
p = Q->front;//你不多此一举这条语句????
Q->front = Q->front->next;
free(p);//何必多此一举????上句不用P
if (!Q->front)//释放队头节点
Q->rear = NULL;
return 1;//出队完成
}
}
5、取队头
int Front_LinkQueue(PLinkQueue Q, DataType *x)
{
PQNode p;
if (Empty_LinkQueue(Q))
{
printf("队空!");
return 0;//队空不能出队
}
else
{
*x = Q->front->Data;
return 1;//出队完成
}
}
6、销毁
void Destroy_LinkQueue(PLinkQueue Q)//??
{
PQNode p;
if (Q)
{
while (Q->front)//队中元素依次释放
{
p = Q->front;
Q->front = Q->front->next;
free(p);
}
free(Q);
}
p = NULL;
}