自学C++我自己曾经碰到了一个问题,链表这玩意儿看起来很简单,每个节点储存一个值和一个指向下一个节点的指针,好多个这样的节点链接起来,就是链表。
但是,到写代码的时候,脑袋就开始打结。可能碰到的问题在很多老手看来就不是问题,但就是想不通。
经常碰到想开门但找不到门的情况。
为了方便新学编程的童鞋,同时也给自己梳理一下链表的理解,所以才有了这篇技术含量极低且幼稚的文章。
struct Node {
int data;
Node* next;
};
首先,从最开始的“造房子”开始,我们需要一个构成链表的节点,这个节点我们可以命名成各种各样的名字,可以是上面的Node,也可以是书上或者PPT上看到比较多的ListNode,这个命名可以随便改,符合自己习惯就行,哪怕命名成a,b或者c都行,只不过以后改代码的时候可就惨了。(程序猿名梗,三个月后只有上帝看得懂的代码)
我们命名了节点之后,需要在里面塞入我们需要的数据,在这个里面,我们命名了data,它的类型是int,也就是整数。
第一个打结点:
之后就是关键点了,也是脑袋打结的第一个地方。Node* next 是个什么东西?
是指针吗?那为啥很多个节点共用一个next,这不重复了吗?
这里不过多探讨这些底层的问题,毕竟这篇文章不是技术流。
我个人的理解,这个Node* next是一个特殊的指针,它存在于每一个创造的节点,作用就是去下一个节点的指示牌。可以理解成像工厂生产出来的指示牌,样子都一样,一个箭头。
这个箭头可以有100个,每个都一模一样的,但是指向的方向是不同的。
╰( ´・ω・)つ──☆*:・゚╰( ´・ω・)つ──☆*:・゚
第二个打结点:
Node* newnode = new Node(0);
Node* head = newnode;
接下来是第二个脑袋打结的点,我故意写了一个很让人爆炸的两行的代码,不知道有多少人和我一样,就是搞不懂节点的创造和指向到底是咋搞的,怎么一堆Node,哪个是哪个?
所以我们敲碎了来看,
new Node(0);
这个是我们创造了一个节点,new在这里表达的意思是我们要创造一个节点,然后调用了我们上面struct Node的功能,然后往里面塞了一个整数0。如果我们上面的命名是ListNode的话,下面的名字也要改变,即:
struct ListNode{
};
new ListNode(0);
然后是第一行的左半边,
Node* newnode
这个可能是大部分人打结的核心点。
这一段到底是啥意思?
很多人有可能认为newnode就是这个新节点的名字,然而这恰恰就是脑袋打结的关键点,这不是节点的名字,这是一个特殊的指针。
它指向这个新创造的节点,并不是这个节点的名字叫newnode。
Node* newnode = new Node(0);
所以综合来看,这一行的意思是:创造了一个节点,然后用一个在Node内专门使用的特殊指针,指向了这个新创造的节点。
Node* head = newnode;
如此,这一段的意思就好理解了,我们又创造了一个特殊的,专门在Node内部使用的指针,head,指向了newnode这个指针。
所以其实,这两个指针都是指的同一个点。
到这里可能有很多人会骂,这代码是啥玩意儿,搞得这么麻烦。
然而这其实就是链表的关键点所在,链表其实就是一堆指针指来指去,最后达成访问一个个节点的功能。
第三个打结点:
newnode -> data; //使用特殊符号 '->',可以理解成指针newnode访问了此节点的data。
newnode -> next; // 使用特殊符号 '->',可以理解成指针newnode访问了此节点的next。
head -> data; //使用特殊符号 '->',可以理解成指针head访问了此节点的data。
head -> next; // 使用特殊符号 '->',可以理解成指针head访问了此节点的next。
最后一块,也就是'->'符号是啥意思。为了大家的理解,我建议直接简化这个符号意思是“访问”。
在指针newnode指向节点的情况下,我们可以使用这个符号访问此节点储存的内容。
同理,head通过指向newnode的方式,最终指向了新节点,他们的值是相同的,即:
newnode->data = head->data = 0
newnode->next = head->next = null
最后的最后,我们如何移动节点呢?
//虽然这篇文章中不存在下一个节点,但是假如需要移动的话。
newnode = newnode->next;
head = head->next;