(这题考的是链队列的出队,几乎书本例题,考试有两题 左右)
1.Int DeQueue(LinkQueue *Q,ElemType *e)
{ LinkQueueNode *p;
If(Q->front=Q->rear)
Return False;
P=Q.front->next ; (从队头取出第一个结点))
*e=p->data;
Q.front->next=p->next (结点P出队)
If(Q->rear==p)
Q->rear=Q->front//是销毁队列的意思吗?
Free(p);
Return true; }
1 回答
I_尼克哇
TA贡献56条经验 获得超25个赞
只是单独看DeQueue这个函数不能直观的了解相关用途,要知道Q->rear=Q->front 是什么意思,需要了解初始化函数的实现:
//初始化队列
Status InitQueue(LinkQueue &Q){
//初始化的节点并未给data赋值,相当于头结点,我们可以用他来存队列长度
Q.front = Q.rear = (QueuePtr)malloc(sizeof(Node)); //注意front和rear指针指向的是同一个内存地址
if(!Q.rear){
exit(OVERFLOW);
}
Q.front->data = 0;//长度初始化为0
Q.front->next = NULL;
return OK;
}上面初始化队列初始化了一个头节点,利用Node这个结构做两件事,1. 存储队列长度。2. front->next指针将来是要指向最早进入队列的一个结点地址;rear->next是要指向最后进入队列的一个结点地址。
再看入队函数:
//入队
Status EnQueue(LinkQueue &Q,ElemType e){
//申请结点空间,用来存储新的结点数据
QueuePtr p = (QueuePtr)malloc(sizeof(Node));
if(!p){
exit(OVERFLOW);
}
p->data = e; //将具体数据e存储到data中
p->next = NULL; //新进来的结点下一个肯定是空的,所以这里赋值NULL
Q.rear->next = p;//连接p节点,将上一个结点的next指针指向到最后进来的结点地址(空的队列上一个结点就是首结点,front和rear都指向这里)
Q.rear = p;//移动rear指针始终指向尾部,将指向上一个结点地址的rear移动指向到最后进来的结点
Q.front->data++;
return OK;
}看出队函数:
//出队,早进早出
Status DeQueue(LinkQueue &Q,ElemType &e){
if(Q.rear == Q.front){//队列为空,初始化队列时两个指针指向到同一个地址,所以相同的时候就是空队列
return ERROR;
}
QueuePtr p = Q.front->next;//跳过头结点,头结点是存储队列长度的,但next指向了最早进入队列的结点
e = p->data; //实际数据
Q.front->next = p->next; //在注销p结点之前,应该把头结点的next指向到p的下一个结点
if(p == Q.rear){//如果除了头结点外只有一个节点,重点来了,Q.rear因为指向的是最后一个结点地址,这里意思就是如果p是最后一个结点
Q.rear = Q.front;//将Q.rear复位会首结点,如果不执行这步,free(p)后Q.rear也将不复存在并成为野指针
}
free(p);
Q.front->data--;
return OK;
}- 1 回答
- 0 关注
- 6577 浏览
添加回答
举报
0/150
提交
取消
