c语言数据结构栈与队列


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
typedef struct QueueNode {
    struct QueueNode* next;
    QDataType data;
} QNode;
typedef struct Queue {
    QNode* head;
    QNode* tail;
} Queue;
void QueueInit(Queue* pq) {
    assert(pq);
    pq->head = NULL;
    pq->tail = NULL;
}
void QueueDestroy(Queue* pq) {
    assert(pq);
    QNode* cur = pq->head;
    while (cur != NULL) {
        QNode* next = cur->next;
        free(cur);
        cur = next;
    }
    pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x) {
    assert(pq);
    //开辟一个新的结点
    QNode* newnode = (QNode*)malloc(sizeof(QNode));
    newnode->data = x;
    newnode->next = NULL;
    if (pq->head == NULL) {
        pq->head = pq->tail = newnode;
    }
    else {
        pq->tail->next = newnode;
        pq->tail = newnode;
    }
}
void QueuePop(Queue* pq) {
    assert(pq);
    if (pq->head == NULL) {
        return;
    }
    QNode* oldhead = pq->head;
    pq->head = oldhead->next;
    if (pq->head == NULL) {
        pq->tail = NULL;
    }
    free(oldhead);
}
QDataType QueueFront(Queue* pq) {
    assert(pq);
    return pq->head->data;
}
QDataType QueueBack(Queue* pq) {
    assert(pq);
    return pq->tail->data;
}
int QueueSize(Queue* pq) {
    assert(pq);
    int size = 0;
    QNode* cur = pq->head;
    while (cur != NULL) {
        size++;
        cur = cur->next;
    }
    return size;
}
bool QueueEmpty(Queue* pq) {
    assert(pq);
    return pq->head == NULL;
}
void TestQueue1() {
    Queue q;
    QueueInit(&q);
    QueuePush(&q, 1);
    QueuePush(&q, 2);
    QueuePush(&q, 3);
    QueuePush(&q, 4);
    while (!QueueEmpty(&q)) {
        printf("%d ", QueueFront(&q));
        QueuePop(&q);
    }
    printf("\n");
}
int main(int argc, char* argv[]) {
    TestQueue1();
    return 0;
}

  1. 在QueuePop中,需要两个断言,一个断言pq,另外一个断言pq->head,在判断空的时候也是这样,也是为什么呢
  2. 断言一个pq不为空不就够了吗

基于Monster 组和GPT的调写:

断言是一种用于在程序中检查和验证条件是否满足的工具。它通常在开发和调试阶段使用,用于捕捉潜在的错误和问题。

QueuePop函数中,有两个断言:

  1. assert(pq):这个断言用于确保pq指针不为空。这是必要的,因为如果传入的指针为空,那么在函数内部就无法访问队列的任何成员,会导致错误。

  2. assert(pq->head):这个断言用于确保队列的头节点指针head不为空。在QueuePop函数中,它检查队列是否为空。如果队列为空,即没有任何节点,那么就没有节点可以出队列,因此函数直接返回,不执行出队列操作。这个断言确保在出队列之前,确实存在一个头节点。

这两个断言的目的是增加程序的健壮性,确保在执行相应的操作之前,必要的条件得到满足,从而避免潜在的错误和异常情况。

在函数QueuePop中,两个断言的目的不一样。就像住酒店,先得有酒店,再确保酒店有空房间,然后才能入住,两个不同的断言。
断言 assert(pq); 用于确保pq不为NULL,以避免在访问pq的成员之前出现空指针错误。
断言 assert(pq->head); 用于验证队列是否为空。在队列为空时,pq->head为NULL。这个断言确保在执行出队操作之前,队列不为空。