为了账号安全,请及时绑定邮箱和手机立即绑定

Q->rear=Q->front//是销毁队列的意思吗?

Q->rear=Q->front//是销毁队列的意思吗?

溯源1 2017-06-27 20:50:55
(这题考的是链队列的出队,几乎书本例题,考试有两题 左右) 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;
}


查看完整回答
反对 回复 2017-06-28
  • 1 回答
  • 0 关注
  • 6396 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信