我正在开发一个删除双向链表节点的函数 . 这是我的头文件:
class LinkedList
{
private:
struct Node
{
int data;
Node *next;
Node *previous;
};
int count;
Node *head;
Node *tail;
public:
LinkedList() {head = NULL; tail = NULL; count = 0;} //Constructor
void insert(const int );
bool remove(const int );
bool contains(const int );
size_t lenght() {return count;}
};
我的其他函数工作正常,但它的删除函数在运行时断开 . 当我运行我的代码时,我得到了一个分段错误,经过2天的尝试找出我逻辑中的缺陷后,我转向社区寻求帮助 . 我很感激此时的任何反馈,谢谢 . 这是我的删除功能:
bool LinkedList::remove(const int item)
{//if the list is empty returns false
if(head == NULL) {return false;}
Node *hptr = head;
Node *tptr = tail;
if((hptr -> data) == item)
{//if the node is at the head of the list
hptr = hptr -> next;
delete head;
hptr -> previous = NULL;
head = hptr;
--count;
return true;
} else if((tptr -> data) == item) {
//if the node is at the tail of the list
tptr = tptr -> previous;
delete tail;
tail = tptr;
tptr -> next = NULL;
--count;
return true;
} else {//if the node is in he middle of the list
Node *ptr_head = head; Node *ptr_headp = NULL;
Node *ptr_tail = tail; Node *ptr_tailp = NULL;
while((ptr_head -> data) != item || (ptr_tail -> data) != item)
{//pointers pass each other then data was not found
if((ptr_tail -> data) < (ptr_head -> data)) {return false;}
//traversing the list from the head and tail simultaniously
ptr_headp = ptr_head;
ptr_head = ptr_head -> next;
ptr_tailp = ptr_tail;
ptr_tail = ptr_tail -> previous;
}
if((ptr_head == ptr_tail) && ((ptr_tail -> data) == (ptr_head -> data)))
{//the item is at the intersection of both head and tail pointers
ptr_headp -> next = ptr_tailp;
ptr_tailp -> previous = ptr_headp;
delete ptr_head;
delete ptr_tail;
--count;
return true;
}
if((ptr_head -> data) == item)
{//the item is before middle node
ptr_headp -> next = ptr_head -> next;
(ptr_head -> next) -> previous = ptr_headp;
delete ptr_head;
--count;
return true;
}
if((ptr_tail -> data) == item)
{//the item is after the middle node
ptr_tailp -> previous = ptr_tail -> previous;
(ptr_tail -> previous) -> next = ptr_tailp;
delete ptr_tail;
--count;
return true;
}
}
return false;
}
2 回答
这是一个常见的例子,当改变数据结构时,通过统一看起来不同的情况*可以使逻辑变得非常简单 .
逻辑的主要问题是您有很多条件需要检查:
删除后面有其他节点的第一个节点
删除前面有其他节点的最后一个节点
删除唯一的节点
删除中间的节点
通过确保左侧始终有节点和任何节点右侧的节点,您可以使这四个条件与最后一个条件相同 . 以下是如何做到这一点:
head
指针是headTail
的next
;tail
指针是previous
. 下一个和上一个点都在一个空列表中回到自身 .这样效率有点低,因为
headTail
的data
未使用 . 该列表变为循环,始终存在一个节点 . 使用此节点,您可以安全地删除中间的任何节点,并更新前一个和下一个指针,就好像它们属于不同的对象一样 .*这是一个非常好的阅读,与手头的问题没有直接关系,但对于理解这种方法的哲学非常有用 .