当我想用纯C语言解决leetcode.225时,出现了问题

问题描述

''' 在答案的帮助下,我修改代码,例如返回类型和函数参数设置。谢谢大家,但是我仍然不明白为什么我的代码仍然报告这样的错误。我检查了很多信息,觉得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->q1st->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的工作方式。

对于堆栈,通常通常以相同的方式进行推入和弹出操作。那确实会简化您的代码。而且,它的性能会更好。

如果您始终从正面推动并弹出,

  1. 删除q2中的MyStack

  2. 删除rear中的struct Queue

,因此删除所有在这些代码上运行的代码。