当前位置: 首页 > 知识库问答 >
问题:

双链表哨兵法

何雅惠
2023-03-14

我在Java双向链表,我在书的双向链表中阅读哨兵。其中指出

为了避免在双链接列表的边界附近操作时出现一些特殊情况,可以在列表的两端添加特殊节点:列表开头的头节点和列表末尾的尾节点。这些“虚拟”节点称为Sentinel(或guards),它们不存储主序列的元素

那些特例是什么?为什么我们需要哨兵接近?这是强制性的吗?如果我们对双向链表使用普通方法(没有哨兵),不会节省这些额外节点的内存吗?当用循环方法制作双链表时,我们必须删除哨兵?

共有1个答案

上官凯歌
2023-03-14

维基百科注释简要提到使用sentinel节点简化链表的实现。

前哨节点是位于列表前面的虚拟节点。

在双链接列表中,哨兵节点指向列表的第一个和最后一个元素。我们不再需要为列表的头部和尾部保留单独的指针,就像我们必须处理单链接列表一样。

我们也不必担心头指针和尾指针的更新,因为正如我们将看到的,如果我们在sentinel节点之后插入,从而在列表中预先插入一个项,或者在sentinel节点之前插入,从而在列表中追加一个项,那么这种情况就会自动发生。

我们可以删除用于单链表的容器对象,因为哨兵节点可以跟踪列表中的第一个和最后一个元素。如果我们这样做了,那么我们将向用户返回指向哨兵节点的指针。

然而,数据结构通常设计有一个容器对象,该容器对象介导数据结构的用户和数据结构的实现之间的通信,因此我们将保留容器对象。

@6502关于哨兵节点如何比空节点提供好处的回答?这很有帮助。

以下是双链接节点列表中删除节点的代码,其中NULL用于标记列表的结尾,first和last两个指针用于保存第一个和最后一个节点的地址:

// Using NULL and pointers for first and last
if (n->prev) n->prev->next = n->next;
        else first = n->next;
if (n->next) n->next->prev = n->prev;
        else last = n->prev;

这是相同的代码,其中有一个特殊的虚拟节点来标记列表的结束,列表中第一个节点的地址存储在特殊节点的下一个字段中,列表中的最后一个节点存储在特殊虚拟节点的prev字段中:

// Using the dummy node
n->prev->next = n->next;
n->next->prev = n->prev;

同样的简化也适用于节点插入;例如,在节点x之前插入节点n(x==NULL或x==

// Using NULL and pointers for first and last

n->next = x;
n->prev = x ? x->prev : last;
if (n->prev) n->prev->next = n;
        else first = n;
if (n->next) n->next->prev = n;
        else last = n;

// Using the dummy node
n->next = x;
n->prev = x->prev;
n->next->prev = n;
n->prev->next = n;

如您所见,对于双链表,所有特殊情况和所有条件都删除了虚拟节点方法。

 类似资料:
  • 主要内容:一、哨兵,二、源码分析,三、总结一、哨兵 Sentinel(哨兵),听名字大家都应该想得到这个家伙是做什么的。在redis的应用中,有单机模式、主从模式、哨兵模式和集群模式,其实你从它的发展就可以看出来,redis是从一个简单的应用开始,不断的壮大,从单点到分布式,从简单的主从备份以及初始的哨兵监控,再到可以看成把二者合成的集群模式,除了是应用场景的变化,更多的是为了提高安全性和高可用性。网上有很多人问哨兵和集群有啥不一样,其实

  • Redis 哨兵(Sentinel)是 Redis 的高可用性(Hight Availability)解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。 Sentinel

  • 每一个哨兵都可以连接到我的主人,并可以看到奴隶。它们能够独立地检测主从是否倒下。问题是哨兵们无法探测到对方。 我已经验证了每个哨兵都像预期的那样向通道发布消息,但似乎没有一个哨兵真正从其他哨兵通道接收消息。 我怎么让哨兵们见面?

  • 主要内容:哨兵模式原理,哨兵模式应用,sentinel.conf配置项在 Redis 主从复制模式中,因为系统不具备自动恢复的功能,所以当主服务器(master)宕机后,需要手动把一台从服务器(slave)切换为主服务器。在这个过程中,不仅需要人为干预,而且还会造成一段时间内服务器处于不可用状态,同时数据安全性也得不到保障,因此主从模式的可用性较低,不适用于线上生产环境。 Redis 官方推荐一种高可用方案,也就是 Redis Sentinel 哨兵模式,它弥补了主

  • 我一直在读有关Redis sentinel用于故障转移的文章。我计划有1主+1从,如果主倒下超过1分钟,把从变成主。我知道这在哨兵身上是百分之百可能的。 null 与1个哨兵相比,多个哨兵有什么好处?我的应用程序一次只能连接到1个哨兵,即使有2个哨兵,如果其中一个在应用程序层中出现复杂的逻辑,我的应用程序也不能在其中任何一个之间旋转或切换。

  • 我正在与一个远程合作伙伴开发一个Laravel项目。 我没有安装mcrypt,所以每次需要使用composer时,我都会通过别名引用php: 这是一个很好的修复,直到我的远程朋友安装了哨兵软件包,这是我无法做到的。 使用另一个stackoverflow线程,我能够使用mcrpyt引用正确版本的php,更新composer并安装sentry。 我的问题是: Sentry在我搭档的本地主机上工作,我将