从双循环链表中删除所有具有相同值的元素
Delete all elements with same value from doubly circular linked list
我有双重循环链表
struct Element {
int data;
Element *next;
Element *previous;
};
struct List {
Element *head;
};
任务是删除具有相同数据的元素/节点。例如,如果列表有 1,1,3,4,5,1,并且在解析函数值 = 1 后,它应该如下 3,4,5。
bool removeAllValue(List &l, int value) {
if(!l.head)
return false;
else if(l.head->next == l.head && l.head->data == value){
l.head = NULL;
return true;
}
Element *p = l.head;
do{
if(p->data == value)
removeElement(l, p);
p = p->next;
}while(p!=l.head);
return true;
上面是遍历元素的函数,查找具有给定值/数据的元素并调用以下函数来删除元素。
void removeElement(List &l, Element *element){
Element *previous = element->previous;
Element *next = element->next;
Element *head = l.head;
if(next == head){ //if element is tail of the list
l.head->previous = element->previous; // relinking head's previous to new tail
element->previous->next = head;
}else if(element == head){ // if element is head of the list
l.head = next; // relinking head to tail
l.head->previous = previous; // relinking tail to head
}else{
previous->next = next;
next->previous = previous;
}
delete element;
}
我尝试了不同的方法,但它总是给我错误。正如我认为的那样,问题在于重新链接尾巴和头部,但我找不到修复它的方法。
我认为你可以简化它。不需要以不同的方式处理removeElement
中的删除尾部/头部/中间情况,唯一的额外任务是在删除前头部时重置列表的头部。我宁愿确定列表中的下一个元素和最后一个项目删除检测。喜欢这个:
Element* removeElement(List &l, Element *element) {
Element *newnext;
Element *previous = element->previous;
Element *next = element->next;
Element *head = l.head;
previous->next = next;
next->previous = previous;
newnext = next;
if (element == head) { // if element is head of the list
l.head = next; // set the head correctly
}
if (element == newnext) // detect if last element in the list was deleted
l.head = newnext = nullptr;
else if (newnext == head) // detect if next is at the head again
newnext = nullptr;
delete element;
return newnext;
}
然后,您不必从删除元素的每个 tiem 的头部重新迭代,也不必将单个项目列表作为特殊情况处理:
bool removeAllValue(List &l, int value) {
if (!l.head)
return false;
Element *p = l.head;
do {
if (p->data == value)
{
p = removeElement(l, p);
}
else
{
p = p->next;
if (p == l.head)
p = nullptr;
}
} while (p);
return true;
}
问题出在很少的重新链接操作中
void removeElement(List &l, Element *element){
Element *previous = element->previous;
Element *next = element->next;
Element *head = l.head;
if(element->next == element)
l.head = NULL;
else if(next == head){ //if element is tail of the list
Element *newTail = previous;
newTail->next = l.head;
l.head->previous = newTail;
}else if(element == head){ // if element is head of the list
l.head = next; // relinking head
l.head->previous = previous; // relinking tail to head
previous->next = l.head; // relinking head to tail
}else{
previous->next = next;
next->previous = previous;
}
delete element;
}
正如Marek Fekete所注意到的那样,每次删除元素时,我都不会更改迭代指针。所以我只是从头开始遍历所有列表,每次我删除一个元素。
bool removeAllValue(List &l, int value) {
if(!l.head)
return false;
else if(l.head->next == l.head && l.head->data == value){
l.head = NULL;
return true;
}
Element *p = l.head;
bool end = false;
while(!end){
do{
if(p->data == value){
Element *tmp = p;
p = p->next;
removeElement(l, tmp);
break;
}else
p = p->next;
if(p==l.head || l.head == NULL){
end = true;
break;
}
}while(p);
}
return true;
}
相关文章:
- 使用std::list创建循环链表
- 循环链表:无限循环
- 打印循环链表
- C++循环链表删除,计数从下一个节点开始
- C++ 循环链表的递归基本情况
- 循环链表的内存错误:未分配正在释放的指针
- 返回指向循环链表某个点的指针
- 在 for 循环(链表)中删除两次后,变量不可用
- 尝试拆分循环链表.显示输出但崩溃.在 IDEone 中显示运行时错误
- 如何打印出双向循环链表
- 循环队列和循环链表
- 我想在我的代码中实现一个双重循环链表 - 运行时错误
- 用C++打印出循环链表
- 把元素放在链表的最后
- 需要帮助编码迭代器的循环链表在c++
- 获取单个非循环链表中指针后面节点的值
- 删除循环链表中的节点
- 具有不同元素的链表,可能
- 循环链表的循环开始节点
- 如何将链表转换为循环链表