C++ 拒绝排序双链接列表中重复项的最佳方法是什么

C++ 拒绝排序双链接列表中重复项的最佳方法是什么,c++,vector,iterator,duplicates,doubly-linked-list,C++,Vector,Iterator,Duplicates,Doubly Linked List,我正在尝试创建一个排序的双链接列表,该列表不插入重复项,但我很难找到一种方法来实现这一点。我看了一些关于如何删除重复的帖子,但没有关于防止重复插入的帖子 下面是我必须插入和排序的代码,而不拒绝重复的代码。参数dataIn从main(Student s={{gpa,name},…{gpa,name})中预定义的Student对象列表中获取值: void StudentList::insertNode(Student dataIn) { ListNode *newNode; // A new

我正在尝试创建一个排序的双链接列表,该列表不插入重复项,但我很难找到一种方法来实现这一点。我看了一些关于如何删除重复的帖子,但没有关于防止重复插入的帖子

下面是我必须插入和排序的代码,而不拒绝重复的代码。参数dataIn从main(Student s={{gpa,name},…{gpa,name})中预定义的Student对象列表中获取值:

void StudentList::insertNode(Student dataIn)
{
    ListNode *newNode; // A new node pointer
    ListNode *pCur; // To traverse the list
    // Allocate a new node and store num there.
    newNode = new ListNode;
    newNode->stu = dataIn;
    newNode->forw = NULL;
    newNode->back = NULL;
    
    //Check if there is node in list
    if(head ->forw == NULL && head->back == NULL){
        head->forw = newNode;
        newNode->back = head;
        newNode->forw = head;
        head->back = newNode;
    }
    else{
        // Initialize pointers
        pCur = head->forw;
        // Find location: skip all nodes whose name is less than dataIn's name
        while (pCur != head && pCur->stu.name < dataIn.name)
        {
            pCur = pCur->forw;
        }
        // Insert the new node between pPre and pCur
        ListNode *pPre = pCur->back; // The previous node
        newNode->back = pPre;
        newNode->forw = pCur;
        pCur->back = newNode;
        pPre->forw = newNode;
    }
    // Update the counter
    count++;
}
void StudentList::insertNode(学生数据输入)
{
ListNode*newNode;//新节点指针
ListNode*pCur;//遍历列表
//分配一个新节点并将num存储在那里。
newNode=新的ListNode;
newNode->stu=dataIn;
newNode->forw=NULL;
newNode->back=NULL;
//检查列表中是否有节点
if(head->forw==NULL&&head->back==NULL){
head->forw=newNode;
newNode->back=头部;
newNode->forw=头部;
head->back=newNode;
}
否则{
//初始化指针
pCur=头部->前方;
//查找位置:跳过名称小于dataIn名称的所有节点
while(pCur!=head&&pCur->stu.nameforw;
}
//在pPre和pCur之间插入新节点
ListNode*pPre=pCur->back;//上一个节点
newNode->back=pPre;
newNode->forw=pCur;
pCur->back=newNode;
pPre->forw=newNode;
}
//更新计数器
计数++;
}
有人知道一种不用删除就可以拒绝重复的方法吗?谢谢大家

拒绝排序双链接列表中重复项的最佳方法是什么

我建议延迟创建新的
ListNode
,直到您知道新节点不是重复节点

假设
ListNode
如下所示

struct ListNode {        
    Student stu;
    ListNode *back;
    ListNode *forw;
};
学生列表
为空时,您有一个
头部
尾部
列表节点*被设置为
nullptr
,那么
插入节点
函数可能如下所示:

bool StudentList::insertNode(const Student& dataIn) { // return true if node is inserted
    ListNode* prev = nullptr;
    ListNode* pCur = head;

    // search for a good insertion spot
    for(; pCur; prev = pCur, pCur = pCur->forw) {
        if(dataIn.name == pCur->stu.name) return false; // equal, reject
        if(dataIn.name < pCur->stu.name) break;         // found a good spot before pCur
    }

    // delayed creation until here:
    ListNode* newNode = new ListNode{dataIn, prev, pCur};

    // linking        
    if(prev) prev->forw = newNode;
    else head = newNode;
    
    if(pCur) pCur->back = newNode;
    else tail = newNode; // comment this line out if you don't have a "tail"

    ++count;

    return true; // node inserted
}
bool StudentList::insertNode(const Student&dataIn){//如果插入了节点,则返回true
ListNode*prev=nullptr;
ListNode*pCur=头部;
//寻找一个好的插入点
对于(;pCur;prev=pCur,pCur=pCur->forw){
如果(dataIn.name==pCur->stu.name)返回false;//等于,则拒绝
if(dataIn.namestu.name)break;//在pCur之前找到一个好位置
}
//将创建延迟到此处:
ListNode*newNode=新ListNode{dataIn,prev,pCur};
//连接
如果(prev)prev->forw=newNode;
else-head=newNode;
如果(pCur)pCur->back=newNode;
else tail=newNode;//如果没有“tail”,请将此行注释掉
++计数;
返回true;//已插入节点
}

当你尝试某件事但它不起作用时,请不要问“什么是通往XYZ的最佳方式”的问题。相反,要问一个关于实际问题的问题。如果有更好的方式,可能会有人在确定问题的同时指出这一点。第一步是编写
bool StudentList::contains(const Student&s)当列表中已经有一个
Student
等于
s
时返回true的const
方法。第二步是将
if(contains(dataIn))return;
添加到
insert()
方法的顶部。在
while(pCur!=head&&pCur->stu.name
循环的末尾,有三种可能性。1)
pCur==head
-您已经走了一整圈,
dataIn.name
比所有其他名称都小;2)
pCur->stu.name>dataIn.name
-您找到了一个插入新名称的位置;3)
pCur->stu.name==dataIn.name
-已经存在同名的节点,
dataIn
是重复的,应该被拒绝。您不需要任何额外的数据结构。当您“检查列表中是否有节点”时,您会执行
if(head->forw==NULL).
但在插入第一个节点之前不是
head==NULL
?如果是,您不能执行
head->forw
head->back
“这就是插入发生的地方”-不完全是,当您更新
back
forw
指针时,插入发生在while循环之后。但这两种方式都无关紧要:while循环找到了节点应该插入的位置,所以你可以在那一刻(在更新pCur之后,或者在while循环之后)检查你是否找到了一个相等的节点。这是我一直在寻找的简单解决方案。谢谢你的帮助!