如何在双向链表中移动元素?

时间:2015-06-13 18:30:53

标签: c++ algorithm sorting data-structures

我的代码中实现了自定义列表(双链表而不是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移动到列表中的第一个就会出错)

3 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分:1)

按设计工作?

在模式中跟踪代码后,表明它按设计运行:

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) 
   }

这里的架构(抱歉幼稚的方面;-)):

enter image description here

所以这份名单实际上很好。问题是ElemList当然包含指向列表头部的指针。而且这个指针仍然指向旧的第一个元素和现在的第二个元素。因此,该列表不再是合理的。

如何解决?

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

答案 2 :(得分:0)

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

 //**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;
           }