C语言 基于位置从链表创建子列表



我正在尝试键入一个函数,需要2链表。其中一个包含要打印的值,第二个包含要打印的链表值的位置。它给了我一个错误,我把它作为代码中的注释。

结构

typedef int Item;
typedef struct node_struct * link;
typedef struct list_struct * list;
struct node_struct {
    Item item;
    link next;
};
struct list_struct {
    link first;
    int length;    
};

功能:

list sublist(list A, list pos_list) {
    link tempOne;
    link tempTwo;
    link node = malloc(sizeof *node);
    tempOne = pos_list->first;
    tempTwo = A->first;
    int counter;
    while(tempOne->next != NULL)
    {
        counter = 0;
        while(counter < tempOne->item && tempOne->next != NULL)
        {
            tempTwo = tempTwo->next;
            counter = counter+1;
        }
        node->item = tempTwo->item; //EXC_BAD_ACCESS code:1
        node = node->next;
        tempTwo = A->first;
        tempOne = tempOne->next;
        counter = 0;
    }
    return node;

代码中有一堆不好的做法,这使得理解(从而调试和维护)这样的代码对你和我们来说都非常困难。

  • 当不打算隐藏指针后面的实际数据时,您正在创建指针typdef
  • 您正在创建位置链表和数据链表,使用相同的数据类型。在你的情况下,我理解两者都是int,但不要使用误导性的typedef int Item,只需坚持使用int
  • tempOnetempTwo可能是最糟糕的命名选项,在这种情况下,不仅调用具有非直观名称的变量,如temp,而且还将第一个参数称为Two,第二个参数称为One -作为反直觉的,因为它可以得到
  • 我可以看到你使用2种不同的结构node_struct(坦率地说,我会称之为node)和list_struct(参见node_struct注释)的情况,但在这个例子中,你不需要list_struct,它只会给代码增加更多的混乱。
  • 你应该在一个单独的函数中做"查找"工作(内部for loop),这样你就可以很容易地处理错误,而不会混淆内部循环和外部循环

在此基础上,您没有指定pos_list实际上是否包含相对位置(从前一个位置的位置)或绝对位置(如数组索引)。我将假定它是绝对位置。

在你做node = node->next;之后,你需要再次做malloc。或者更确切地说,在node->item = tempTwo->item;行使用它之前将其malloc,并将malloc从循环中删除

我手边没有c编译器,所以不能测试它。但我看不出有其他问题

编辑

我注意到sublist的返回值总是最后一个节点,而不是链表中的第一个节点——这显然也是一个问题。

下面是我将如何编写这段代码。请记住,这不是经过调试和测试的代码,而仅仅是想法的表达(如果您愿意,可以是初稿)
typedef struct Node_ Node;
struct Node_ {
    int Item;
    Node* Next;
};
Node* GetNodeAt(Node *dataList, int indx) {
    for (int i = 0; i < indx && dataList != NULL; ++i)
        dataList = dataList->Next;
    return dataList;
}
Node* SubList(Node *dataList, Node *posList) {
    Node* origDataList = dataList;
    Node *currentRetNode = malloc(sizeof(Node));
    Node *prevRetNode = NULL, *returnList = currentRetNode;
    while (posList->Next != NULL) {
        // Find the node in dataList
        Node *node = GetNodeAt(dataList, posList->Item);
        // create/manage the linked list to be returned
        prevRetNode = currentRetNode;
        currentRetNode->Next = malloc(sizeof(Node));
        currentRetNode->Item = node->Item;
        currentRetNode = currentRetNode->Next;
        posList = posList->Next; // move to the next index
    }
    free(currentRetNode);
    if (prevRetNode == NULL)
        returnList = NULL;
    else
        prevRetNode->Next = NULL;
    return returnList;
}

最新更新