我正在编写一个应该删除链表的最后一个元素的函数
这是我对节点的定义
struct Node {
int key;
Node* next;
};
我有一个节点列表1,它为值1,2,3
运行插入函数3次插入功能如下所示
void insert( Node*& head, int key) {
Node * curr = new Node;
curr->key = key;
curr->next = head;
head = curr;
}
现在我的delete_last_element函数看起来像这样
void delete_last_element( Node*& head )
{
Node *curr;
if (head == NULL)
return;
curr = head->next;
if (curr == NULL){
delete head;
head = NULL;
return;
}
head = curr;
while (curr->next != NULL) {
head = curr;
curr = curr->next;
}
delete head->next;
head -> next = NULL;
}
基本上我的想法是我首先会看到第一个元素是否为null,如果是,那么我什么都不做,因为没有最后一个元素。然后我将curr设置为head->接下来查看列表中的下一个元素,如果为null我将删除head,因为我知道它是最后一个元素并返回。
现在我知道第一个元素不是最后一个元素,我将头部分配给curr或第二个元素。从这里我进入while循环并检查下一个元素(从第3个开始)是否为null,如果是,我删除当前元素,如果不是,我移动到下一个元素,然后检查后面的元素。 / p>
现在我的链接列表最初以3 2 1开头,但无论出于何种原因,当我运行delete_last_element函数时,它变为2而不是3 2.
谁能告诉我自己可能做错了什么?
由于
答案 0 :(得分:0)
在你的插入功能中,你总是设置在指向头部旁边:
curr->next = head;
最重要的是,你正在改变你的头脑,
head = curr;
这是链表中的最后一项。所以你实际上是在意外地向后制作链表。
要把它画出来,这就是你在做什么;向下箭头指向头部,箭头指向下一个方向
插入1:
|
v
1
插入2 :(您正在创建一个新节点:2,然后您正在创建它接下来是前一个头,即1,然后您将当前节点2设置为新头)
|
v
1 <- 2
插入3:
|
v
1 <- 2 <- 3
答案 1 :(得分:0)
在这个例子中,基本上你需要注意两个条件:
如果列表为空,则由指向head
的{{1}}指针指示。如果没有列表,则无法删除任何内容,因此我们可以退出该功能:
nullptr
检查列表中是否只有一个元素的原因是有用的,如果我们保留两个遍历列表的指针 - 一个指向当前元素,一个指向当前元素。 &#34;之前&#34;在删除当前节点后,指针必须将其if (head == nullptr)
return;
指针设置为next
。如果没有上一个节点(因为只有一个元素),那么我们就不能使用前一个指针。
nullptr
现在我们必须遍历列表以找到最后一个元素。您不应该使用if (!head->next)
{
delete head;
head = nullptr;
return;
}
node *prev = nullptr, // previous is nullptr
*curr = head; // start at head
来遍历列表,因为需要head
来表示列表的开头,您不能将其指向其他位置,因此我们使用head
代替
curr
现在我们已经到达列表的末尾,我们可以删除while (curr->next)
{
prev = curr;
curr = curr->next;
}
并将之前的指针curr
设置为next
:
nullptr
就是这样。这是完整的方法:
delete curr;
prev->next = nullptr;
Here is a demo showing its use
了解上述代码后,您可以了解如何缩短代码。
void delete_last_element(node*& head)
{
if (head == nullptr) // list is empty, nothing to do
return;
if (head->next == nullptr) // only one element in list
{
delete head;
head = nullptr; // set back to nullptr
return; // get outta here
}
node *prev = nullptr,
*curr = head;
while (curr->next)
{
prev = curr;
curr = curr->next;
}
delete curr;
prev->next = nullptr;
}
答案 2 :(得分:0)
递归在这里很有用。列表是:
- 空
- 只有一个元素
- 有多个元素
醇>
我们按以下方式处理这三种情况:
void delete_last_element( Node*& head ) {
if(head == NULL) {
// The list is empty, nothing to remove.
// Just do nothing and return
return;
}
else if (head->next == NULL) {
// This list has exactly one element.
// Remove it and return
delete head; // free the memory
head = NULL; // the single-element list is now an empty list
return;
}
else {
// We have a list with more than one element.
// Let's be lazy
delete_last_element(head->next);
return;
}
依次处理这三个案件中的每一个案件。最后一种情况(“具有多个元素的列表”)仅通过调用delete_last_element(head->next);
来处理。我们的想法是删除从head
开始的5元素列表中的最后一个元素与删除以head->next
开头的4元素列表完全相同。