You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中基于栈实现链表反转的节点数据赋值与遍历入栈问题咨询

如何用栈实现线性链表反转(解决元素入栈的核心困惑)

咱们先理清楚你卡壳的地方:你已经有了链表和栈的结构定义,也知道反转的大致步骤,但不知道怎么遍历链表的所有节点并把数据依次压入栈,还有代码里(???)的赋值问题。我一步步帮你拆解:


首先解决你代码里的(???)问题

你当前的代码只创建了一个栈节点,却没有遍历整个链表——这就是为什么只能保存第一个节点的原因。首先要明确:你的LinkedList里的head是一个占位节点,真正的第一个数据节点在pList->head.next里。

你需要用循环遍历链表的每一个节点,把每个节点的data依次压入栈。比如:

void reverseList(LinkedList* pList, StackNode** top){
    Node *current = pList->head.next; // 拿到第一个数据节点
    while (current != NULL) {
        // 这里就是你要的(???):当前链表节点的data
        StackNode* sNode = (StackNode*)malloc(sizeof(StackNode));
        sNode->data = current->data; 
        sNode->next = *top;
        *top = sNode; // 更新栈顶
        
        current = current->next; // 移动到下一个链表节点,循环遍历
    }

    // 后续还要处理出栈重建链表的逻辑,往下看
}

其实你参考的push函数完全可以复用,把current->data作为参数传进去就行,不用单独写栈节点的创建逻辑:

void reverseList(LinkedList* pList, StackNode** top){
    Node *current = pList->head.next;
    while (current != NULL) {
        push(current->data, top); // 直接调用你参考的push函数
        current = current->next;
    }
    // ... 出栈重建链表
}

完整的reverseList实现(入栈+出栈重建)

反转链表的完整流程是:遍历链表入栈 → 清空原链表 → 出栈元素重新构建链表。这里给你补全完整代码:

// 先实现配套的pop函数,和你的push对应
int pop(StackNode** top){
    if (*top == NULL) {
        // 栈为空的边界处理,返回特殊值或根据需求报错
        return -1;
    }
    StackNode *temp = *top;
    int data = temp->data;
    *top = temp->next;
    free(temp);
    return data;
}

// 完整的反转函数
void reverseList(LinkedList* pList, StackNode** top){
    // 第一步:遍历链表,所有元素入栈
    Node *current = pList->head.next;
    while (current != NULL) {
        push(current->data, top);
        current = current->next;
    }

    // 第二步:清空原链表的所有数据节点(保留头节点)
    Node *temp;
    current = pList->head.next;
    while (current != NULL) {
        temp = current;
        current = current->next;
        free(temp);
    }
    pList->head.next = NULL;
    pList->curCount = 0;

    // 第三步:从栈中弹出元素,重新插入链表
    int data;
    while (*top != NULL) {
        data = pop(top);
        // 新建链表节点,插入到头节点之后(栈是后进先出,直接插头部即可)
        Node *newNode = (Node*)malloc(sizeof(Node));
        newNode->data = data;
        newNode->next = pList->head.next;
        pList->head.next = newNode;
        pList->curCount++;
    }
}

关于你想修改push函数的疑问

你提到想让push不再传int data,而是传LinkedList* pList——其实没必要这么做,因为push的职责就是接收一个数据并压入栈,遍历链表取数据的逻辑放在reverseList里更清晰,代码解耦性更好。

如果硬要把遍历逻辑整合到push里(不推荐,违反单一职责),可以写一个专门的函数:

void pushAllFromList(LinkedList* pList, StackNode** top){
    Node *current = pList->head.next;
    while (current != NULL) {
        StackNode *sNode = (StackNode*)malloc(sizeof(StackNode));
        sNode->data = current->data;
        sNode->next = *top;
        *top = sNode;
        current = current->next;
    }
}

调用时直接传pList和top就能把整个链表元素压入栈,但还是建议拆分逻辑,代码更易维护。


内容的提问来源于stack exchange,提问作者dooroomi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 18:03:08