问题描述
''' 在答案的帮助下,我修改了代码,例如返回类型和函数参数设置。谢谢大家,但是我仍然不明白为什么我的代码仍然报告这样的错误。我检查了很多信息,觉得enqueue函数中的代码没有错。怎么了?非常感谢你 ! '''
typedef struct {
int val;
struct QNode* next;
}QNode;
typedef struct {
struct QNode *rear;
struct QNode *front;
}Queue;
typedef struct {
struct Queue *q1;
struct Queue *q2;
}MyStack;
Queue* qcreate(void){
Queue* q = malloc(sizeof(Queue));
q->front = NULL;
q->rear = NULL;
return q;
}
bool qisempty(Queue* q){
return (q->rear == NULL);
}
void enqueue(Queue *q,int x){
QNode *qn = malloc(sizeof(QNode));
qn->val = x;
qn->next = NULL;
if(q->front==NULL){
q->front = q->rear = qn; // line 35
}
else{
q->rear->next = qn; // line 38
q->rear = qn;
}
}
int dequeue(Queue* q){
QNode *pt;
int n = q->front->val;
pt = q->front;
q->front = q->front->next;
free(pt);
return(n);
}
void freeq(Queue* q){
while(!qisempty(q)){
dequeue(q);
}
q->front = q->rear = NULL
free(q);
}
/** Initialize your data structure here. */
MyStack* myStackCreate() {
MyStack* st = (MyStack*)malloc(sizeof(MyStack));
st->q1 = qcreate();
st->q2 = qcreate();
return st;
}
/** Push element x onto stack. */
void myStackPush(MyStack* obj,int x) {
int m;
while(!qisempty(obj->q1)){
m = dequeue(obj->q1);
enqueue(obj->q2,m);
}
enqueue(obj->q1,x);
while(!qisempty(obj->q2)){
m = dequeue(obj->q2);
enqueue(obj->q1,m);
}
}
/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
int m;
m = dequeue(obj->q1);
return m;
}
/** Get the top element. */
int myStackTop(MyStack* obj) {
return obj->q1->front->val;
}
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
return qisempty(obj->q1);
}
void myStackFree(MyStack* obj) {
freeq(obj->q1);
freeq(obj->q2);
}
/**
* Your MyStack struct will be instantiated and called as such:
* MyStack* obj = myStackCreate();
* myStackPush(obj,x);
* int param_2 = myStackPop(obj);
* int param_3 = myStackTop(obj);
* bool param_4 = myStackEmpty(obj);
* myStackFree(obj);
*/`enter code here`
solution.c:在“入队”功能中
第35行:字符28:警告:从不兼容的指针类型“ QNode *”(又名“ struct *”)分配给“ struct QNode *” [-Wincompatible-pointer-types] q->前= q->后= qn; ^
第38行:字符16:错误:将指向不完整类型“ struct QNode”的指针取消引用 q->后方->下一个= qn; ^〜
解决方法
您的错误在这里:
void qinit(){
您这样称呼它:
qinit(st->q1);
qinit(st->q2);
显然,您希望函数初始化st->q1
和st->q2
,但不会初始化。您可能想要:
void qinit(){
....
return MALLOCED_AND_INITIALIZED_QUEUE_POINTER;
}
st->q1 = qinit();
st->q2 = qinit();
那为什么不收到编译器警告/错误?
好吧,void qinit()
表示一个函数,该函数采用未指定个参数,因此不会对qinit(st->q1);
发出警告。
您曾经使用过:void qinit(void)
编译器会对您大喊大叫。
课程:切勿在函数中使用空的参数列表。如果不带参数,请使用void
。
除此之外:
这里是一个错误,也需要修复。
这里:
void freeq(struct Queue* q){
while(!qisempty(q)){
dequeue(q);
}
free(q->front); // q-> front is NULL due to the while above
// so this does nothing
free(q->rear); // q->rear is pointing to an already free'ed object
// so this is an error
}
换句话说-应该同时删除两个free
。
在这里:
int dequeue(struct Queue* q){
struct QNode *pt;
int n = q->front->val;
pt = q->front;
q->front = q->front->next;
q->count--;
free(pt);
return(n);
}
您缺少q->rear
的更新。喜欢:
if (q->front == NULL) q->rear = NULL;
return(n);
有关设计的评论:
为什么要在队列末尾推送并从前面弹出?
这就是FIFO的工作方式。
对于堆栈,通常通常以相同的方式进行推入和弹出操作。那确实会简化您的代码。而且,它的性能会更好。
如果您始终从正面推动并弹出,
-
删除
q2
中的MyStack
-
删除
rear
中的struct Queue
,因此删除所有在这些代码上运行的代码。