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

C语言链表实现栈式DFS遍历未完整输出,请求排查问题

问题排查:DFS遍历仅输出单个顶点的错误修复

问题描述

用C语言实现基于链表栈的深度优先搜索(DFS),构建包含两个互连顶点a、b的图后,执行DFS遍历仅输出顶点a,预期输出为a b,需排查代码错误。

原代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct node
{
    char data;
    struct node *next;
};

struct node *head = NULL;

struct edge {
    char data;
    struct edge *next;
};

struct vertex {
    char data;
    struct vertex *next;
    struct edge *enext;
};

void push(char item);
char pop();
bool isEmpty(struct node *head);
void printGraph(struct vertex *v);

int n; // 顶点数量
char d; 

int main(void) 
{
    struct vertex *v = NULL;
    printf("Enter the no. of vertices: ");
    scanf("%d", &n);
    char status[2][n];
    printf("Enter the vertices of the graph:\n");
    char c;

    // 读取顶点
    for (int i = 0; i < n; i++) 
    {
        scanf(" %c", &c);
        struct vertex *new = malloc(sizeof(struct vertex));
        new->data = c;
        new->next = v;
        v = new;
    }

    printf("Press $ to stop for the particular vertex\n");
    struct vertex *ptr = v;
    for (int i = 0; i < n; i++)
    {
        printf("Enter the vertices with which the vertex %c forms an edge:\n", ptr->data);
        ptr->enext = NULL;
        char input;

        while(1) 
        {
            scanf(" %c", &input);

            if (input == '$') 
            {
                break;
            }

            // 为当前顶点添加邻接边
            struct edge *new = malloc(sizeof(struct edge));
            new->data = input;
            new->next = ptr->enext;
            ptr->enext = new;
        }
        ptr = ptr->next;
    }
    // 打印图结构
    printGraph(v);

    // DFS初始化
    for (int i = 0; i < n; i++) 
    {
        status[1][i] = '1'; // 1表示未访问
    }

    struct vertex *pointer = v;
    for(int i = 0; i < n; i++) 
    {
        status[0][i] = pointer->data;
        pointer = pointer->next;
    }

    d = v->data;
    push(d);
    status[1][0] = '2'; // 2表示已入栈

    while(!isEmpty(head))
    {
        char temp = pop();
        printf("%c ", temp);

        // 更新弹出顶点的状态为已访问(3)
        for (int i = 0; i < n; i++)
        {
            if (status[0][i] == temp)
            {
                status[1][i] = '3';
                break;
            }
        }

        // 查找当前顶点的所有邻居
        struct vertex *ptr = v;
        for (int j = 0; j < n; j++)
        {
            if (temp == ptr->data)
            {
                struct edge *ptr1 = ptr->enext;
                while (ptr != NULL) 
                {
                    for(int i = 0; i < n; i++) 
                    {
                        if(ptr->data == status[0][i])
                        {
                            if (status[1][i] == '1')
                            {
                                d = status[0][i];
                                push(d);
                                status[1][i] = '2';
                                break;
                            }
                        }
                    }
                    ptr1 = ptr1->next;
                }
            }
            ptr = ptr->next;
        }
    }
}

void push(char item)
{
    struct node *newNode = malloc(sizeof(struct node));
    newNode->data = item;
    newNode->next = head;
    head = newNode;
    printf("Item inserted.\n");
}

char pop()
{
    if(head == NULL)
        printf("UNDERFLOW: Stack is Empty\n");
    else
    {
        char deletedItem = head->data;
        head = head->next;
        return deletedItem;
    }
}

void printGraph(struct vertex *v)
{
    struct vertex *ptr = v;
    for (int i = 0; i < n; i++)
    {
        printf("%c ------> ", ptr->data);
        struct edge *ptr1 = ptr->enext;
        while (ptr1 != NULL)
        {
            printf("%c", ptr1->data);
            printf("-->");
            ptr1 = ptr1->next;
        }
        printf("NULL\n");
        ptr = ptr->next;
    }
}

bool isEmpty(struct node *head)
{
    return head == NULL;
}

运行输出

Enter the no. of vertices: 2
Enter the vertices of the graph: 
b
a
Press $ to stop for the particular vertex
Enter the vertices with which the vertex a forms an edge:
b
$
Enter the vertices with which the vertex b forms an edge:
a
$
a ------> b-->NULL
b ------> a-->NULL
Item inserted.
a 

错误分析与修复

1. 邻接边遍历循环条件错误

DFS模块中,查找当前顶点邻居时,错误地使用while (ptr != NULL)作为循环条件(ptr是当前顶点节点,不会为空),实际应遍历邻接边链表,使用ptr1作为循环指针,正确条件为while (ptr1 != NULL)。

2. 邻居顶点匹配错误

循环内部错误地用当前顶点的ptr->data匹配状态数组,实际应使用边节点的ptr1->data(邻居顶点的标识)来判断是否未访问。

3. Pop函数空栈返回值缺失

当栈为空时,pop()函数未返回有效数据,会导致未定义行为,需添加默认返回值。

修复后的核心代码片段

修改DFS中的邻居遍历逻辑:

// 查找当前顶点的所有邻居
struct vertex *ptr = v;
for (int j = 0; j < n; j++)
{
    if (temp == ptr->data)
    {
        struct edge *ptr1 = ptr->enext;
        // 修复:遍历邻接边链表
        while (ptr1 != NULL) 
        {
            for(int i = 0; i < n; i++) 
            {
                // 修复:匹配邻居顶点的标识
                if(ptr1->data == status[0][i])
                {
                    if (status[1][i] == '1')
                    {
                        d = status[0][i];
                        push(d);
                        status[1][i] = '2';
                        break;
                    }
                }
            }
            ptr1 = ptr1->next;
        }
        // 找到当前顶点后退出循环,无需继续遍历
        break;
    }
    ptr = ptr->next;
}

修改pop()函数添加空栈返回值:

char pop()
{
    if(head == NULL)
    {
        printf("UNDERFLOW: Stack is Empty\n");
        return '\0'; // 添加默认返回值
    }
    else
    {
        char deletedItem = head->data;
        head = head->next;
        return deletedItem;
    }
}

修复后的运行输出

Enter the no. of vertices: 2
Enter the vertices of the graph: 
b
a
Press $ to stop for the particular vertex
Enter the vertices with which the vertex a forms an edge:
b
$
Enter the vertices with which the vertex b forms an edge:
a
$
a ------> b-->NULL
b ------> a-->NULL
Item inserted.
a Item inserted.
b 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 09:07:03