[英]Node deletion in a doubly-linked list
我正在使用一個函數,該函數將刪除雙向鏈接列表的節點。 這是我的頭文件:
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;}
};
我的其他功能運行良好,但其刪除功能在運行時中斷。 當我運行我的代碼時,我遇到了段錯誤,在嘗試找出我的邏輯缺陷兩天后,我正在向社區尋求幫助。 感謝您在這一點上的反饋。 這是我的刪除功能:
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;
}
這是一個常見的情況,當稍微改變數據結構可以通過統一看起來不一樣的情況使邏輯變得非常簡單* 。
邏輯的主要問題是您需要檢查許多條件:
通過確保在任何節點的左側始終都有一個節點,在右側的每個節點,可以使這四個條件與最后一個條件相同。 這是您可以執行的操作:
class LinkedList
{
private:
struct Node
{
int data;
Node *next;
Node *previous;
};
int count;
// The change begins here
Node headTail;
// End of the change
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;}
};
head
指針是headTail
的next
; tail
指針是它的previous
指針。 下一個和上一個指向空列表中的自身。
這是有點低效的,因為headTail
的data
未使用。 列表變成循環的,始終有一個節點。 使用此節點,您可以安全地刪除中間的任何節點,並更新前一個和下一個指針,就好像它們屬於不同的對象一樣。
// Locate the item to remove
Node* to_remove = head;
while(to_remove && to_remove->data != item)
to_remove = to_remove->next;
// Do the removal if we found it
if(to_remove)
{
// If it was at the head, advance the head to the next item
if(to_remove == head)
head = head->next;
// If it was at the tail, advance the tail to the previous item
if(to_remove == tail)
tail = tail->previous;
// Remove from the list
if(to_remove->next)
to_remove->next->previous = to_remove->previous;
if(to_remove->previous)
to_remove->previous->next = to_remove->next;
// Free the removed node
delete to_remove;
count--;
return true;
}
return false;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.