C++ 拒绝排序双链接列表中重复项的最佳方法是什么
我正在尝试创建一个排序的双链接列表,该列表不插入重复项,但我很难找到一种方法来实现这一点。我看了一些关于如何删除重复的帖子,但没有关于防止重复插入的帖子 下面是我必须插入和排序的代码,而不拒绝重复的代码。参数dataIn从main(Student s={{gpa,name},…{gpa,name})中预定义的Student对象列表中获取值: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
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循环之后)检查你是否找到了一个相等的节点。这是我一直在寻找的简单解决方案。谢谢你的帮助!