(这题考的是链队列的出队,几乎书本例题,考试有两题 左右)
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 关注
- 6396 浏览
添加回答
举报
0/150
提交
取消