Java代码实战:通过手写一个单链表,告诉你学习编程的方法和捷径!

  • 日期:03-16
  • 点击:(1189)


读者们,你们现在能写一个链接列表吗?

到目前为止,我经常收到一些读者的微信,他们向我抱怨,“为什么我能看视频或书,却不能写代码?”

哈哈,这是我们一直在说的话吗:“当你看到它,你就做错了”?不要谈论你,我相信每个新手程序员都会遇到这样的问题。读一本书会让他觉得他理解并知道正在发生的事情。然而,一旦他写了自己的代码,他要么没有办法开始,要么充满了错误,这真的伤害了他的信心。

为了学习编程,很多人也会问我有没有捷径。我通常回答“多观察,多练习”。然而,实际情况是许多人看得多,练得少。这实际上是一个主要的罪魁祸首(有许多因素导致他们自己),导致许多人一目了然,立刻犯错误,并随着时间的推移忘记。尤其是对于代码,他们应该敲得更多!

今天,我将以一个链表为例来谈谈写代码。我将带你一步一步地写一个简单的单链表,在中间我将不断地向你解释如何练习代码。其中一些思维方法也非常重要。

了解你的敌人和你自己,你就可以不战而败。

第一步是写代码。也就是说,你必须理解你想写什么样的代码。例如,今天我们将使用java来实现一个链表。所以,你必须知道什么是链表。这是前提。如果你甚至不知道什么是链表,你能写什么?

此外,你不仅要知道,而且要深刻理解,这样你才能轻松地编写相应的代码。以链接列表为例,你可能不知道什么是链接列表,但是,嗯,你花10分钟随便找一篇文章,也许你能知道一个关于链接列表的大概想法,但是即使如此,如果你意识到一个链接列表,你可能还是写不出来。

简单的理解并不会让你编写代码变得容易。您还需要彻底了解一些关键知识,例如链表中的指针。事实上,java中没有指针。相反,它可以说是一个参考。然而,当编写链表代码时,我们通常说指针和下一个指针。因此,对于手写的单个链表,您不仅应该理解什么是链表,还应该理解指针的含义。

至于链表,我以前写过一篇文章,详细讨论过链表。我建议那些不熟悉链表的人回顾一下今天的实战部分:链表不起作用吗?看看这个,马上就明白了!

你不能急着吃热豆腐

对于手写的单链表,在了解了链表的相关知识后,我们将分析如何实现单链表。当我们第一次做这样的操作时,我们不想一次自己编写代码。我认为那是不可能的。首先,我们可以简单地写下来。代码可以写得不那么优雅和有效,但是我们必须实现最少的功能。然后,我们可以彻底理解这些基本的简单操作,并不断迭代我们的代码。

你知道,好文章都是经过修改的,代码也是一样的!

所以这次,我们将实现一些简单的功能,比如向列表中添加一个新节点,然后删除一个节点。当然,我们也可以查看存储在列表中的数据,也就是打印列表。

链表是一个重要的知识点,我们应该一步一步的攻克它,不要想着一次吃掉一个胖子,并且要记住链表的所有相关代码。

如何定义这个节点?

我想你已经知道什么是链表,所以我们首先需要考虑的是如何定义链表中的节点,记住链表的结构,它看起来像这样:

在链表中,它是由一个接一个的节点组成的,所以当我们实现一个链表时,我们首先需要定义一个节点,在Java中,一切都是一个对象,所以,首先,我们应该考虑用一个类来表示一个节点,也就是一个节点类。那么,这个班的名字是什么?通常,它是节点。来吧,写代码

在这里定义一个节点。链表中的一个节点是这样的:

包含两个部分,一个是真实数据,另一个是保存下一个对象的下一个指针,它实际上是下一个节点对象的引用,所以我们编写代码:

可以吗?我们认为链表在最终的分析中是用来存储数据的,所以我们应该在创建节点时将数据插入其中吗?这个代码是如何产生的?很容易想到,你可以使用构造函数,就是这样:

好,我们已经定义了这样一个节点,现在我们有了一个节点,我们将开始写我们的单个链表,让我们先命名它,让我们称它为我的链表。

添加节点

接下来,我们将实现第一个功能,即添加节点。事实上,这里涉及到很多问题,比如什么样的哨兵节点,什么样的头插,什么样的尾插和中间插。我们没有那么多麻烦。让我们先设定一个场景前提:

没有链表,我们需要创建一个,然后直接添加到尾部。

这很容易理解。所以让我们开始编写代码:

这里我们首先需要定义一个头节点。为什么我们需要定义这个头节点?因为链表必须先有一个节点,然后再添加一个接一个的节点,所以只有当有一个头节点,也就是第一个节点时,剩下的节点才是自然的。顺便说一下,我们定义的节点类也将被添加。这是内部类的方式:

编写我们添加节点的方法:

考虑如何编写它,我们首先想到的是还没有链表。我们添加第一个数据,也就是添加的头节点,所以我们首先处理头节点:

这个逻辑很简单,不需要再解释了,这实际上是第一次添加节点时创建头节点的操作,那么,有头节点吗?这是如何添加头节点。那么在下一步中添加新节点就是在前面的节点之后一个接一个地链接新节点。应该如何做呢?

code如上,对于这些代码,第一次编写链表代码的学生应该理解并记住,这里的核心是通过遍历找到链表的尾部节点。为什么,因为我们又添加了新的节点,它规定尾部是在前面添加的,所以我们的重点是找到这个尾部代码,然后理解为什么要写这样一个代码:

为什么我们要定义一个临时节点出来?首先,你认为,我们必须遍历以找到尾部节点,它必须从头部节点遍历,但现在我们不知道这个尾部节点是谁,并且头部节点是固定的,所以我们需要定义一个新的临时节点,从头部节点开始,我们可以向后移动一次,并在移动尾部节点时将其复制到尾部节点,所以最好表达,仔细思考。

然后是循环代码:

显然,这是寻找尾部节点的遍历。temp的next指的是头节点后面的节点。如果它不是空的,这意味着头节点后面有节点,那么临时节点将继续向后移动。如何向后移动?现在这个临时节点指向头节点,对,你知道,如果它向后移动,它也指向头节点后面的节点。也就是说,头节点的最后一个节点被分配给这个临时节点,情况就是这样:

然后,直到这个临时节点后面没有节点,也就是说,它是空的,执行这些代码:

此时,这个临时节点临时指向尾节点,然后向气候添加一个新节点,也就是说,为它的下一个节点分配一个新节点。

这样,我们就完成了添加节点的操作。总体代码如下:

删除节点

我们知道如何添加节点。接下来,我们将看看如何删除节点。首先,我们将看看下面的链表:

我们将看看这个链表。如果我们删除数据2,我们是否必须将数据1的下一个指向数据3,即数据1。下一个=数据3?我们必须牢记这个概念。

接下来,让我们看看如何编写这个被删除的代码。如果我们写这个删除,我们必须考虑删除的基础。我们之前定义了一个大小来表示链表的长度,增加一个节点就会增加一个。你认为是否可以把链表的节点按照连接的顺序编号,也就是说,有一个索引,那么当我们在这里删除它们的时候,我们就会按照这个索引删除它们。

然后我们必须考虑,有一些特殊情况:

首先是空的链表,然后是跨境索引,我认为这很容易理解。我不会说太多。我们为删除的节点编写的代码将返回删除的节点。在处理头节点时,被删除的头节点应该如何返回到头节点?我的鹅湖粗粒度在这里定义了一个临时节点,在开始时指向头节点,并在更新头节点后返回原始节点。这些代码并不复杂,更不用说复杂了。

接下来,让我们看看如何从这些特殊情况中删除以下节点。考虑从上述三个节点中删除数据2的操作。此时,你必须清楚。我们必须根据索引进行删除。它不能再是头节点。因为头节点已经根据特殊情况进行了处理,所以我们再次删除,我们需要看看这个索引是什么。我们需要遍历并找到对应于这个索引的节点。

您想不想想,此时我们正在从链表的第二个节点遍历,所以我们首先定义一个索引值int i=2,并知道它为什么等于2,它代表链表中的第二个节点,然后要删除的节点的索引是index,所以我们需要找到这个==index的情况来找到要删除的节点。

然后,让我们仔细看看下图:

事实上,现在我们只知道头节点,然后我们必须遍历头节点下的下一个节点。我们如何表示这个遍历的起点?让我们把它作为当前节点,用cureNode来表示它。这实际上是一个很好的表示,而不是head.next,此时当前节点的索引是2,这很容易理解。如果说,这个索引是2,这意味着我们删除的节点是头节点之后的节点,那么它是头节点的下一个指向当前节点的下一个的节点吗?代码表示是:

当然,这里不应该删除的是头节点之后的节点,所以统一来说:

如果我们要删除当前节点,我们需要让当前节点的前一个节点指向下一个节点所指向的对象。

代码表示是:

那么考虑一下,这里的cureNode和preNode最初应该如何表示,考虑一下,我们最初只知道头节点。这个当前节点也是这样:

这个前节点不是头节点:

所以,除了特殊情况,我们可以通过删除节点代码来写这个:

然后返回到被删除的当前节点,还要注意这个代码:

这实际上是继续向下遍历,直到我们找到要删除的节点,然后依次将cureNde和前节点移回来。

然后删除节点的代码就完成了。整体代码如下:

我应该如何打印链表?

一般来说,我们还需要做一个操作来打印链表。这是为了查看链表的内容,方便做一些测试。那么如何打印链表呢?乍一看,我们似乎不能一眼就看出链表的头或尾。转念一想,我把它擦掉了。不就是从节点开始遍历,然后分别打印出每个节点的数据吗?

来吧,直接添加代码:

经过上面添加节点和删除节点的分析,这个代码已经超出了文字的范围,我们就不多说了。

我认为有必要返回链表的长度。

虽然它真的非常简单:

几乎一样,我们已经在这里完成了链表的最基本和最简单的添加、删除和打印。让我们测试一下,先添加几个节点,然后打印链表长度:

测试结果如下:

石爻,就这样。尝试删除一个节点(删除头节点):

测试结果是:

还不错,继续删除其他节点并尝试,例如,删除最后一个:

测试结果是:

kuiyi,这是一样的

这是渣码

说实话,上面的代码实现真的不是很好,有很多地方可以优化,也有很多地方没有考虑好。然而,这并不是要实现一个美丽而完美的单链表代码,而是要实现一些简单而基本的功能来告诉每个人敲更多的代码是非常重要的。如果你不敲门,你真的不能第一次写它。即使你自己做,你也写不出来。即使你把它写出来,也有很多错误。

但还是同一句话:好文章都被修改了,代码也是如此!

当你开始写作时,你向前迈出了一大步。你只会越来越好,写得越来越流畅,理解得越来越深刻。这就是你的代码能力得到提高的原因。

此外,许多人问,有没有一种学习编程的方法?

答案是肯定的,什么,四个字“多看多练”,尤其是多练!

朋友,拿起你的键盘敲门!

谢谢你阅读

大学。我选择自学Java。工作之后,我发现我的电脑基础很差。要取得好的学习成绩是不可能的。我只能在后天弥补。所以我在代码之外开始了我自己的攻击方式。我继续学习Java核心知识,并彻底学习了计算机基础知识。我所有的经历都被写入并编辑成带有目录的PDF格式,这种格式一直是原创的。公共编号中的PDF不断更新。如果你不愿意平庸,那么你应该和我一起在代码之外成长。

事实上,这里不仅有技术,还有那些技术之外的东西。比如,如何成为一个精致的程序员而不是“潘军宝程序员是一个高尚的存在,是不是?

非常欢迎你加入我们。在未来,除了编码,你和我将成为快乐的程序员,他们不傻,有很多钱,活得很长。

回复关键字“PDF”并获得一组技术文章,这些文章已经被分类并有目录。欢迎一起交流技术!

另外,回复“庆哥”,看看庆哥为你准备的惊喜礼物包,只给第一次注意的你。

如有疑问,请添加清歌微信:H。此外,我还有一个交流小组,我会在小组中不时分享学习资源,并不时从中受益。如果你感兴趣,请说我邀请你!

顺便说一下,如果你是爪哇白,你也可以加我微信。我相信你在学习过程中一定遇到了很多问题。也许我可以帮你,毕竟我也是以前的人了!

非常感谢您的阅读

-