我是C ++的新手,我正在研究链接列表,我遇到了这个问题,但仍然无法找到解决方案。
这是基本节点的样子。
False
我正在尝试用这个函数交换第一个节点和最后一个节点的位置。
struct node {
int data;
node *next;
};
我得到的错误是:抛出异常:读取访问冲突,这个 - >尾部是nullptr。
有谁能解释我做错了什么?
答案 0 :(得分:0)
tail
是最后一个,有一个node::next
指向它,而您没有将其更改为指向temp
head
或tail
是否为空。编辑添加了固定方法
void swap_first_and_last()
{
//if there is less than 2 nodes - finished.
if(!head || !tail || head==tail) return;
node *temp = new node;
node *temp2 = new node;
node *temp3;
temp->data = head->data;
temp->next = NULL;
temp2->next = head->next;
temp2->data = tail->data;
temp3 = head;
head = temp2;
delete temp3; //delete old head
temp3 = tail;
//find the tail previous
for(tail=head; tail->next!=temp3;tail=tail->next);
//make tail previous point to tail
tail->next = temp;
tail = temp;//now it will point to new tail...
delete temp3;//delete old tail
}
更好的解决方案:
void swap_first_and_last()
{
node *temp;
//if there is less than 2 nodes - finished.
if(!head || !tail || head==tail) return;
for(temp=head; temp->next!=tail;temp=temp->next);
temp->next = head; //set tail precedor's next to point to head, prepere for head = tail
tail->next = head->next; //set tail's next to point head->next, prepere for head = tail
head = tail; //set tail as head
tail = temp->next; //set old head as tail
tail->next = NULL; // tail next is always null (was point to the 2nd).
}
答案 1 :(得分:0)
// V----- where does tail get initialized?
temp2->data = tail->data;
调用swap_first_and_last
时,tail
尚未初始化,就像运行时所说的那样:你的时间会很糟糕。
你可以 -
tail
swap_first_and_last
tail
之前是否已初始化
试图对它进行任何读取访问。我认为后者是更好的选择。
if (head) {
temp->data = head->data;
}
if (tail) {
temp2->data = tail->data;
}
你应该问自己一个问题 - 为什么我不把这个初始化放在node
的构造函数中?
答案 2 :(得分:0)
你是C ++的新手,所以我理解这并不是特别容易理解,但是一旦掌握了它,你就会理解上面的评论。
头部和尾部是指针node *head;
,因此您不需要创建它们指向的对象的副本。
head指向具有内容(data = 42; next = tail)的内存块,tail指向保存的内存块(7和null)。您可以将头部复制到temp
并拖至temp2
,然后将其复制回tail
和head
,但为什么?除了内存泄漏之外,通过创建内存块的副本可以获得什么?你不关心内存块,你不想移动它们,你不想改变它们你想要做的就是改变哪个指针指向哪个内存块。
node* pTemp = head;
head = tail;
tail = head;
不幸的是,这会破坏您的列表,因为现在head->next = null
所以您只需要修复它:
pTemp = head->next; // Which should always be null.
head->next = tail->next;
tail->next = pTemp;
现在,如果你把它放在一个以两个指针作为参数的小函数中,那么你就有了一个可以切换列表中任意两个给定节点的代码块,这意味着对列表进行排序变得容易多了。