【问题标题】:Having trouble with inserting nodes in a sorted fashion以排序方式插入节点时遇到问题
【发布时间】:2019-11-13 17:40:45
【问题描述】:

我有一个链表,我必须将对象插入其中,根据对象的一个​​字段,我必须以正确的顺序将节点插入到链表中。

在使用数组和向量时,我的排序工作完美,但在链表的插入方面遇到了麻烦。我的 getLink() 调用用于获取我的链接的函数,即 = next。

void sortedInsert(DomNodePtr& head, string fName, string lName, float CGPA, int rScore,string prov){
     DomNodePtr here = head;
     DomNodePtr tempPtr;
     tempPtr = new DomNode(fName, lName, CGPA, rScore, prov, head);

     while (here->getCumGPA() > CGPA && here->getLink() != NULL){
     here = here->getLink();

     }
     if (here->getCumGPA() < CGPA){
         tempPtr->setLink(here->getLink());
         here->setLink(tempPtr);
     }
     else if (here->getCumGPA() > CGPA){
         here = tempPtr;
     }
}

基本上,我希望累积 GPA 最高的学生排序高于 CGPA 较低的学生。我知道我的部分问题是我没有插入 CGPA 较低的学生,但我正在努力解决这部分问题。当我打印链接列表时,它也输出了大约 10 个学生,而实际上他们大约有 100 个并且它们的顺序不正确。

【问题讨论】:

  • 缩进代码是第一步。
  • @n.m.我为糟糕的格式道歉,我已经解决了。
  • 你真的应该从简单开始而不是这样。你能建立一个简单的int 排序的链表吗?如果可以,请将int 替换为您的班级,因为代码几乎相同。如果您无法为 int 的链表实现它,那么您几乎没有机会尝试为更复杂的类型执行此操作。
  • 尝试找出一个失败的小例子,即最多两三个学生。当你有 100 名学生时,很难弄清楚哪里出了问题。然后使用调试器甚至铅笔和纸来准确跟踪您的代码对链接所做的操作。希望到那时错误所在的位置会变得很明显。
  • @john 非常感谢您的反馈,您太棒了!这实际上是我为解决它所做的。 :)

标签: c++ linked-list nodes singly-linked-list


【解决方案1】:

将新学生插入列表时,有三种情况:

  • 新元素的 CGPA 小于列表中所有元素的 CPGA 值。在这种情况下,学生必须附加到列表的末尾。
  • 学生的 CPGA 大于列表中的所有元素:新元素必须添加到列表的开头
  • 学生在两个现有元素之间有一个 CPGA。在这里,必须在这些 to 元素之间插入新元素。因此,您必须跟踪前一个元素的 CPGA 大于新元素的 CPGA。

    void sortedInsert(DomNodePtr& head, string fName, string lName, float CGPA, int rScore,string prov){
        DomNodePtr here = head;
        DomNodePtr tempPtr;
        tempPtr = new DomNode(fName, lName, CGPA, rScore, prov, head);
    
        DomNodePtr previous = NULL; // keeping track of the previous element
    
        while (here->getCumGPA() >= CGPA && here->getLink() != NULL){
            previous = here;
            here = here->getLink();
        }
        if (here->getLink() == NULL){
            // Insert new student at the end of the list
            // If CPGA is larger for all students in the list
    
            here->setLink(tempPtr);
        }
        else if (previous = NULL) {
            // The new student has the highest CGPA and
            // has to be added at the head of the list
            tempPtr->setLink(here);
        }
        else{
            // Insert the student between the current
            // and the previous elements of the list
    
            previous->setLink(tempPtr);
            tempPtr->setLink(here);
        }
    }
    

【讨论】:

  • 非常感谢,我实际上刚刚想通了,但我非常感谢您的反馈。如果可以的话,我会投票!
  • @kiotzu 有一个巧妙的技巧,您可以使用指向指针的指针来消除跟踪previoustempPtr 节点的需要。不是跟踪here 节点,而是跟踪指向前一个节点的next 的指针,即DomNodePtr *。这同时为您提供了插入点,您希望测试的节点,并隐藏了 head 和任何其他 next 指针之间的一个区别。这可以消除相当多的代码,因为您当前必须跟踪的一些案例不再需要。
  • @user45813015 谢谢你!我会确保牢记这一点。
猜你喜欢
  • 2019-09-06
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
相关资源
最近更新 更多