构建链表结构时。我已经学会了正确的方法,但我不知道为什么一个更简单的方法不起作用。我在互联网上搜索,我买了一本书,我玩了代码和理论,我终于称它退出并愿意在我的问题上处理一些负面因素,如果我错过了什么。所以这就是:
#include <bits/stdc++.h>
using namespace std;
struct Node{
int data;
Node* next;
// Constructor
Node(int data)
{
this->data = data;
next = NULL;
}
};
// Class to represent Red-Black Tree
class LinkedList{
private:
Node* root;
public:
// Constructor
LinkedList() { root = NULL; }
//insert new value into list
void insert(const int n);
//print all values from root to end;
void print();
};
// Function to insert a new node with given data
void LinkedList::insert(const int data){
Node** pp = &root;
while (*pp)
pp = &((*pp)->next);
*pp = new Node(data);
}
void LinkedList::print(){
Node** pp = &root;
while (*pp){
cout << (*pp)->data << " ";
pp = &((*pp)->next);
}
cout << endl;
}
int main(){
LinkedList ll;
ll.insert(5);
ll.insert(2);
ll.insert(22);
ll.print();
return 0;
}
非常简单的东西,它运行得很漂亮。但是,这是一个问题。因为我不知道为什么我不能这样做:
void LinkedList::insert(const int data){
Node* pp = root;
while (pp)
pp = pp->next;
pp = new Node(data);
}
它应该像我在脑海中看到指针的方式一样。当我在纸上写下地址/内容对时,它仍然有意义。
谢谢, -Connor。
答案 0 :(得分:2)
void LinkedList::insert(const int data){
Node* pp = root;
while (pp)
pp = pp->next;
pp = new Node(data);
}
此代码实际上并没有做任何事情。将pp
设置为特定值会遇到很多麻烦,只是忽略该值并重新分配pp
一些其他值。然后它返回,pp
超出范围,它分配给它的值永远丢失。
让我们逐行完成:
void LinkedList::insert(const int data){
Node* pp = root;
此时,pp
是一个等于root
的局部变量。
while (pp)
pp = pp->next;
这会更改pp
的值,直到它从列表末尾开始运行。所以我们已经完成了整个列表,只是最终突破了pp
设置为NULL
。
pp = new Node(data);
我们不会创建新的Node
并更改pp
的值以指向新的Node
。所以我们遇到了麻烦,让pp
指向最后一个节点,然后将其更改为指向新节点。
}
现在我们返回,pp
超出范围,我们也没有对新的Node
做任何事情。
您还可以看到:
void LinkedList::insert(const int data){
Node* pp = root;
while (pp)
pp = pp->next;
pp = new Node(data);
}
等同于(假设它不会永远运行):
void LinkedList::insert(const int data){
Node* pp = root;
pp = NULL;
pp = new Node(data);
}
相当于:
void LinkedList::insert(const int data){
Node* pp = NULL;
pp = new Node(data);
}
相当于:
void LinkedList::insert(const int data){
Node* pp = new Node(data);
}
相当于:
void LinkedList::insert(const int data){
new Node(data);
}
这显然会创建一个新的Node
并立即泄漏它。
答案 1 :(得分:1)
我不喜欢这样做:
void LinkedList::insert(const int data){
Node** pp = &root;
while (*pp)
pp = &((*pp)->next);
*pp = new Node(data);
}
我将使用的是:
// returns the last node or NULL on failure
bool LinkedList::insert(const int data){
Node* pp = root;
if (!pp){ // if it is an empty list
root = new Node(data); // assign it to something
return root; // convert to bool and return - false if new failed
}
while (pp->next) // check if we have a next node
pp = pp->next; // we do have a next node so go there
// at this point pp->next will be NULL
pp->next = new Node(data); // assign it to something
return pp->next; // convert to bool and return - false if new failed
}
答案 2 :(得分:1)
认为指针只是一个存储内存地址的变量类型。例如,int *只是一个变量(&#34;一个盒子&#34;),它存储另一个int变量的地址。
当你进入&#34;插入&#34;功能:
Node* pp;
pp是函数的 local 变量,用于将地址存储到Node对象。从函数返回时,本地变量将被销毁。
当你这样做时:
Node ** pp;
你定义了一个存储地址的局部变量,但不是Node对象,而是指向Node对象的指针,也就是另一个&#34;中间框&#34;将地址存储到Node对象。
最后,当你这样做时:
pp = &((*pp)->next);
你的局部变量,它会在你的函数返回时被销毁,存储到&#34; next&#34;的地址。会员。不喜欢你这样做:
pp = pp->next
您指定给&#34; pp&#34; 存储在&#34; next&#34;中的相同的地址(如果next是0x1234,这是一个表示对象地址的简单值,pp将得到相同的值0x1234),在列表的最后一个对象中为NULL。
用句子:
*pp = new Node(data);
&#34; pp&#34;的内容是指向Node对象的另一个指针的地址(不是直接指向对象),在这种情况下,这是&#34; next&#34;的地址。指针(不是&#34; next&#34;指针的值),以及指定&#34;新节点(数据)&#34;对于pp的内容,您将对象地址分配给&#34; next&#34;指针,它是列表对象的成员,而不是本地变量,你得到的是将新节点链接到列表。
为了更好地理解指针,您可以在纸上绘制变量的结构,将指针绘制为存储地址的框,并将其自己的地址作为变量。