【问题标题】:C++| Merge Linked ListsC++|合并链表
【发布时间】:2015-11-12 01:57:09
【问题描述】:

所以我一直在做关于数据结构的家庭作业,几个小时以来我都陷入了死胡同。为了解释,我必须在文本文件 ListJava 和 ListDS 中获取以下格式的信息:Name Surname NUM Grade。这两个文件包含相同的名称但顺序不同。作业基本上是要我们对文件进行合并排序。

这些是我的结构:

typedef struct student
{
    string name;
    string surname;
    int am;
    int grade;
}StudentFile;
typedef struct node {

    StudentFile element;
    struct node* next;
}Node;

typedef struct stud 
{
    string name;
    string surname;
    int am;
    int grade;
    int grade2;
    struct stud* next;
}Student;

这是我合并它们的函数:

/*Merge Lists into one*/
Student* MergeLists(Node* headDS, Node* headJava, Student* head)
{
    bool flag = false;

    Student *a = new Student;
    Student *prev = NULL;
    Student *temp = NULL;
    Node *tempDS = headDS;
    Node *tempJava = headJava;
    Node *prevJava = NULL;

    if (head == NULL)
    {
        head = a; //mermory alocation for head<Student>
        temp = head;
    //  temp->next = NULL;
    }
    while (tempDS != NULL)
    {

        if(head != NULL)
        {

            if (tempDS->element.surname.compare(tempJava->element.surname) == 0) // if surnames are equal
            {
                prev = temp;

                temp->name = tempDS->element.name;
                temp->surname = tempDS->element.surname;
                temp->am = tempDS->element.am;
                temp->grade = tempDS->element.grade;
                temp->grade2 = tempJava->element.grade;

                tempJava = tempJava->next;
                tempDS = tempDS->next;
                temp = temp->next;
                flag = false; //meaning that prevJava can get a new value again.
            }
            else  // if DS > Java
            {
                /*Keep tempJava in mermory while iterating through the next nodes to find the temp that is equal to DS*/
                if (flag == false)
                {
                    prevJava = tempJava;
                    tempJava = tempJava->next;
                    flag = true;
                }
                else
                {
                    tempJava = tempJava->next;
                }

            }

            /*temp = temp->next;
            tempJava = tempJava->next;
            tempDS = tempDS->next;*/
        }
        prev->next = a;
    }
    a->next = NULL;

    return a;
}

问题出在 temp = temp-> 下一行。虽然第一次运行非常好,然后正确搜索 ListJava 以找到与 ListDS 相同的名称临时值是 0xcdcdcdcd {...} 并且它抛出了一个异常:

Exception thrown at 0x00C38EF0 in Exercise3_zitima2.exe: 0xC0000005: Access violation reading location 0xCDCDCDE5.

我该如何应对这个错误,我真的到处搜索尝试过的东西,但似乎没有任何效果。我知道这当然不是一个找人解决我的任务的地方,只需要一点指导。

【问题讨论】:

  • 请注意,虽然它有效,但您不必执行typedef struct student{ }StudentFile;,而是可以执行struct StudentFile{ }; - 它更清晰且几乎相同。在this post 中了解更多信息。
  • ^这真的很丰富!感谢分享:)

标签: c++ singly-linked-list


【解决方案1】:

您的Student 结构没有构造函数,因此当您分配一个并将其分配给MergeLists 中的a 时,a-&gt;next 中会有垃圾。 (0xCDCDCDCD 是 MSVC 填充已分配内存的内容,因此您可以看到这些未初始化的使用情况。)

您要么需要构造函数将next 指针设置为NULL,要么在分配后手动将其设置为NULL

【讨论】:

  • 很高兴了解 0xCDCDCDCD。那么在 Student 结构中,像这样吗? :学生(){下一个=空; }
  • @NickCh 更好的是,使用构造函数初始化列表:Student(): next(nullptr){}
  • sigh 我试过了还是没用,反正我会继续研究你们的建议,看看我能做些什么
【解决方案2】:

合并列表函数通常用于合并两个已排序的列表。不涉及节点分配。一个列表的第一个节点与另一个列表的第一个节点进行比较。较小的节点从它的列表中删除,并附加到一个最初为空的列表中,该列表将以合并的节点结束。唯一改变的节点成员是下一个指针。重复该过程,直到到达其中一个链表的末尾,然后将添加到合并链表的最后一个节点的next指针设置为指向另一个链表其余部分的第一个节点,完成合并.

【讨论】:

  • 在看到当前算法有效后,我想稍后进行排序。虽然我现在已经完全改变了,但先把它们排序,然后再合并。
猜你喜欢
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 2021-03-07
相关资源
最近更新 更多