迭代链表问题

时间:2017-04-28 21:24:28

标签: c pointers struct

我们说我有以下结构:

// structures
typedef struct student {
    char *name;
    int  id;
    struct clist *courses;
} student;

typedef struct course {
    char *title;
    int  number;
    struct slist *students;
} course;

typedef struct slist {
    student      *info;
    struct slist *next;
} slist;

typedef struct clist {
    course       *info;
    struct clist *next;
} clist;

我们假设clistslist包含内容。 现在我的问题: 我在迭代clistslist结构(链表)时遇到问题。 我创建了下一个为学生课程添加课程的功能:

void reg_student(slist *students,clist *courses,int id,int number){
  clist* Cpointer=courses;
  slist* Spointer=student;

  //finding course location
  for(;Cpointer->info->number!=number;Cpointer=Cpointer->next);

  //find student location
  for(;Spointer->info->id != id;Spointer=Spointer->next);

  //adding course to student courses list
  Spointer->info->courses=Cpointer;
  Spointer->info->courses->next->NULL;
  return;
}

当它开始搜索课程的位置时,会删除他之前的所有课程。 例如,假设我正在寻找课程编号' 555'我在课程列表中有3门课程 - (' 111,' 222,' 333'),一旦功能完成,只需要333' 333'在列表中。

如何在不删除内容的情况下迭代结构?

2 个答案:

答案 0 :(得分:0)

您需要考虑所有权。

当您通过studentscourses,时,这些是列表。他们是什么样的名单?

我怀疑,既然你正在编写这个函数并提出这个问题,那么他们就是“所有学生”和“所有课程”的列表。

因此,如果您要更改其中一个“所有课程”条目中的指针,则会影响所有课程。

这可能不是你想要的。

那么,谁拥有什么?有一个“信息”结构,其中包含有关课程或学生的详细信息。并且有一个“列表”结构,它将列表中的一个项目与列表中的下一个项目联系起来。

课程和学生信息结构可能是普遍的。也许不是一成不变的,但肯定可以分享。我甚至建议分享它们是功能 - 如果有人更改(course){ "CS-204: Introduction to C programming", 77204 }的课程信息,如果这种变化反映在任何地方,这可能是一件好事。

因此,您对信息结构拥有某种“通用”所有权。但个人列表可能是一个不同的故事。可以有一个“所有课程”列表,以及“这个学生正在学习的课程”列表,以及这些列表是不同的。

不同的列表将表示不同的下一个指针。因此,您需要为学生创建单独的列表记录。像这样:

begin register_student(all_students, all_courses, student_id, course_num)

    student = find_student_id(all_students, student_id)
    if !student
        fail or report error

    course = find_course_num(all_courses, course_num)
    if !course
        fail or report error

    new_list_entry = make_new_course_list_entry(course)

    insert_new_course(student, new_list_entry)

答案 1 :(得分:0)

继续奥斯汀的回答,首先,如果没有Minimal, Complete, and Verifiable example,很难说出所有问题可能来自哪里。

然而,看起来你使用4个列表会导致你很难保持指针的正确性(正如Austin在他的回答中指出的那样,每个students需要单独的course列表并且单独{每个courses的{​​1}}列表。我看到的困难是每次迭代学生或课程时都需要一个非常接近递归的列表数量。例如,当您对student进行迭代时,它会包含slist,而clist course *info又会包含sliststudent *info,例如

slist students
    student info
        name
        id
        clist course info
            { multiple inclusions of independent slist follows }
            title
            slist next
        clist next
    slist next

同样适用于clist

clist courses
    course info
        title
        number
        slist students
            { multiple inclusions of independent clist follows }
            ...
    clist next

现在我并不是说你不能填充一个足够大的内存块并用适当的指针地址填充每个指针地址并将其关闭,但是在Aspirin公司购买股票......

为什么不从中解决一些问题,并使用2个结构重做布局,例如:

typedef struct student {
    char *name;
    int  id;
    struct course *courses;
} student;

typedef struct course {
    char *title;
    int  number;
    struct student *students;
    struct course *next;
} course;

现在,您仍然会遇到必须使用单独的student列表构建每个course节点的相同问题,并且您仍然需要使用单独的{course节点构建每个student节点{1}}列表,但这样做会大大减少您需要管理的指针数量。

如果您发布MCVE,我很乐意进一步提供帮助。