求助:在位置链表类中实现无需创建新节点的swap方法
解决位置链表Swap方法的实现问题
嘿,我来帮你搞定这个位置链表的swap方法!首先得明确核心要求:不能创建新节点,只能通过调整现有节点的双向链接来完成交换,还要覆盖各种边界情况(比如两个位置是同一个节点、相邻节点、头尾节点这些)。
先给你完整的实现代码,然后一步步拆解逻辑:
def swap(self, p, q): # 验证位置有效性,获取对应的底层节点 node_p = self._validate(p) node_q = self._validate(q) # 若两个位置指向同一个节点,直接返回无需操作 if node_p == node_q: return # 提前保存两个节点的前驱和后继(后续调整指针会覆盖这些值,必须先存好) prev_p = node_p._prev next_p = node_p._next prev_q = node_q._prev next_q = node_q._next # 情况1:p和q是相邻节点,且p在q的直接前方 if next_p == node_q: # 把q接到p的前驱后面(如果p不是头节点) if prev_p is not None: prev_p._next = node_q else: # p原来是头节点,现在q成为新的头节点 self._head = node_q # 把p接到q的后继前面(如果q不是尾节点) if next_q is not None: next_q._prev = node_p else: # q原来是尾节点,现在p成为新的尾节点 self._tail = node_p # 调整p和q之间的双向链接 node_q._prev = prev_p node_q._next = node_p node_p._prev = node_q node_p._next = next_q # 情况2:p和q是相邻节点,且q在p的直接前方(对称情况,复用逻辑) elif next_q == node_p: self.swap(q, p) # 情况3:p和q不相邻 else: # 将node_p放到node_q原来的位置上 if prev_q is not None: prev_q._next = node_p else: # q原来是头节点,现在node_p成为新头 self._head = node_p if next_q is not None: next_q._prev = node_p else: # q原来是尾节点,现在node_p成为新尾 self._tail = node_p # 将node_q放到node_p原来的位置上 if prev_p is not None: prev_p._next = node_q else: # p原来是头节点,现在node_q成为新头 self._head = node_q if next_p is not None: next_p._prev = node_q else: # p原来是尾节点,现在node_q成为新尾 self._tail = node_q # 最后更新两个节点自身的前驱和后继指针 node_p._prev, node_p._next = prev_q, next_q node_q._prev, node_q._next = prev_p, next_p
关键逻辑拆解
有效性验证与特殊情况处理:
先通过_validate拿到位置对应的底层节点,如果两个节点是同一个,直接返回,避免做无用功。保存前驱后继:
因为调整指针时会覆盖节点的_prev和_next属性,所以必须提前把这些值存下来,不然会丢失原有链接。相邻节点处理:
相邻节点的交换和不相邻的逻辑不一样,需要单独处理。如果q在p前面,直接递归调用swap(q,p)复用前面的代码,减少重复逻辑。同时要注意更新链表的_head和_tail——如果原来的节点是头尾,交换后要更新对应的指针。不相邻节点处理:
核心是把两个节点分别放到对方原来的位置:先调整目标位置的前驱后继指向当前节点,再更新当前节点的前驱后继指针,同样要检查是否需要更新链表的头尾。
这个实现完全符合你的要求:没有创建任何新节点,只是调整了现有节点的双向链接,覆盖了所有可能的边界情况。
内容的提问来源于stack exchange,提问作者Hoon Lee
相关产品推荐
相关产品推荐

