为什么在构建链表C++时必须指向指针
Why do I have to point to a pointer when building a linked list C++
构建链表结构时。我已经学会了正确的方法,但我不知道为什么更简单的方法不起作用。我搜索了互联网,买了一本书,我玩了代码并进行了理论化,我终于宣布退出,如果我只是错过了什么,我愿意在我的问题上处理一些负面问题。所以这里是:
#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);
}
它应该像我在脑海中看到指针一样做同样的事情。当我在纸上写下地址/内容对时,它仍然有意义。
谢谢-康纳。
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
并迅速泄漏它。
我也不喜欢这种方式:
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
}
认为指针只是存储内存地址的变量类型。例如,int* 只是一个变量("一个盒子"(,用于存储另一个 int 变量的地址。
当您在"插入"功能中执行此操作时:
Node* pp;
pp 是函数的局部变量,用于存储 Node 对象的地址。从函数返回时,局部变量将被销毁。
当您执行以下操作时:
Node ** pp;
定义一个局部变量,该变量也存储地址,但不存储到 Node 对象,而是存储指向 Node 对象的指针,即另一个存储 Node 对象的地址的"中间框"。
最后,当您这样做时:
pp = &((*pp)->next);
你的局部变量,当你的函数返回时,它将被销毁,存储到"下一个"成员的地址。不像你这样做的时候:
pp = pp->next
您为"pp"分配存储在"next"中的相同地址(如果 next 是0x1234,这是一个表示对象地址的简单值,pp 将获得相同的值 0x1234(,该地址在列表的最后一个对象中将为 NULL。
用这句话:
*pp = new Node(data);
"pp"的内容是另一个指向Node对象(而不是直接对象(的指针的地址,在这种情况下,这是"next"指针的地址(不是"next"指针的值(,当你将"new Node(data("分配给pp的内容时,你正在将对象地址分配给"next"指针, 它是列表对象的成员,而不是局部变量,您得到的是将新节点链接到列表。
为了更好地理解指针,您可以在论文中绘制变量的结构,将指针绘制为存储地址的框,并具有自己的地址作为变量。
- 函数向量_指针有不同的原型,我可以构建一个吗
- 如何在构建链接列表时调整头、尾指针
- 使用C对象指针构建PyObject*
- 有关为指向运行时确定的多个结构之一的指针构建类的建议
- 在编译时以增量方式构建变量指针的向量
- OpenCV使用像素指针构建图像
- 从双指针构建箭头双环
- 为什么在构建链表C++时必须指向指针
- 我是否正确构建了这些引用和指针函数?如果是,我该如何显式调用我的析构函数
- 为什么由指针和对象构建的局部变量显示不同的输出
- 确保仅构建智能指针
- PHPBREW 5.3.10 构建错误:取消引用指向不完整类型的指针
- 当我传递从字符串流构建的字符指针时,流打开(..)失败
- C++ 构建警告:取消引用类型双关指针将违反严格锯齿规则
- 使用 Rice 在 C++ 中构建 Ruby 扩展:如何将 Ruby 方法(回调)的指针传输到C++函数
- xcode 构建错误:从指针到较小类型"int"的语义问题丢失了信息
- Boost -在构建时关于解引用指针的警告
- 在c++中构建/合并字符数组指针
- 试图创建一个指向父节点的指针,同时构建二叉树
- new(size, value) Type[0]返回的指针是否合法,是否可以用来构建数组?