【问题标题】:How to move elements in doubly linked list? [closed]如何移动双向链表中的元素? [关闭]
【发布时间】:2015-06-13 18:30:53
【问题描述】:

我在我的代码中实现了自定义列表(双向链表而不是 std::list)。我的要求是通过更新引用将元素向左或向右移动。有可能吗?

class Elem
{
  Elem *next;
  Elem *prev;
}

.......

void move_element_left(Elem *e)
   {
    if(e->prev()==NULL)
      return;           //Left most ... so return

    Elem *left = e->prev();

    left->next() = e->next();
    e->prev() = left->prev();

    if (left->next())
        left->next()->prev() = left;

    if (e->prev())
        e->prev()->next() = e;

    e->next() = left;
    left->prev() = e;
   }

.......

int main()
{
  ElemList ls;
  ...
  ...
  move_element_left(e);  //e of type Elem *
  ...
}

除了列表中我想移到最左边(或最上面)的第二个对象之外,上面的代码都有效。 (即如果列表(obj5,obj9,obj11,obj12,..),将 obj9 移动到列表中的第一个会出错)

【问题讨论】:

  • 调试你的代码,或者画一张图看看发生了什么。
  • @Harry Kodz 您可以在不更改引用的情况下交换节点的值。:)
  • @Harry Kodz 你还应该展示 ElemList 是如何定义的。
  • @vsoftco 嗯,他去报名绘画课了。:)

标签: c++ algorithm sorting data-structures


【解决方案1】:

Bubble-sorting doubly linked list

我假设你的 Elem 类也包含数据,所以移动数据或 - 如果它是一个简单的数据指针 - 交换指针:C++ Swapping Pointers

如果这不可能,我会 - 从“不要重复自己”的角度来看 - 重用您很可能已经拥有的那些简单的链表函数:

void move_element_left(Elem *e)
{
    Elem *left = e->prev();

    if(left)
    {
        remove_element(e);
        insert_element_before(e, left);
    }
}

【讨论】:

    【解决方案2】:

    按设计工作?

    在架构中遵循您的代码,表明它按设计工作:

    void move_element_left(Elem *e)
       {
        if(e->prev()==NULL)
          return;                  //ok ! Left most ... so return
        Elem *left = e->prev();    // ok ! (1)
        left->next() = e->next();  // ok ! (2)
        e->prev() = left->prev();  // ok ! (3)
    
        if (left->next())          // ok !
            left->next()->prev() = left;   // ok ! (4)
    
        if (e->prev())             // ok ! e prev is left prev is null
            e->prev()->next() = e; 
    
        e->next() = left;          // ok ! (5)
        left->prev() = e;          // ok ! (6) 
       }
    

    这里的架构(对不起,幼稚的方面;-)):

    所以列表实际上很好。问题是ElemList 肯定包含指向列表头的指针。这个指针仍然指向旧的第一个元素和现在的第二个元素。因此,该列表不再是一致的。

    如何解决?

    一种方法是让move_element_left() 成为ElemList 的成员函数。在这种情况下,您可以处理 e->left 变为 null 的特殊情况,在这种情况下,您需要更新 ElemList 指向第一个元素的指针。

    【讨论】:

      【解决方案3】:

      以下是更新后的代码。 如果左指针指向双链表的头,则需要更改头指针

       //**head is the address of pointer of head of double linked list
      
                  void move_element_left(Elem *e,Elem **head)
                 {
                  if(e->prev()==NULL)
                    return;           //Left most ... so return
      
                  Elem *left = e->prev();
                  if(left==*head){
                   *head=e;
                   }
      
                  left->next() = e->next();
                  e->prev() = left->prev();
      
                  if (left->next())
                      left->next()->prev() = left;
      
                  if (e->prev())
                      e->prev()->next() = e;
      
                  e->next() = left;
                  left->prev() = e;
                 }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多