Преобразование односвязного списка в двусвязный список

У меня есть один связанный список для программы, которая делает коллаж. Это работает отлично, но мне было интересно, как сделать его двойным связанным списком. Я действительно понятия не имею, что такое двойная ссылка или как ее создать. Любая помощь будет оценена ...

Есть 3 класса.

class LinearCollage
{
  private Picture myArray[];
  private class Node
  {
    Picture data;
    Node pNext;
  };

  private Node pFirst;
  private Node pLast;

  private int nPictures;  
  private Picture clipboard;
  public LinearCollage()
  {
    pFirst = null;
    pLast = null;
    nPictures = 0;

  }
  public void addPictureAtEnd(Picture aPictureReference)
  {
    Node temp = new Node();
    temp.data = aPictureReference;
    temp.pNext = null;
    if( pLast == null )
    {
      pLast = temp;
      pFirst = temp;
    }
    else
    {
      pLast.pNext = temp;
      pLast = temp;
    }
    nPictures++;
  }
  public Picture makeCollage()
  {
    int collageHeight = 400;
    int collageWidth = 400;
    for( Node finger = pFirst; finger != null; finger = finger.pNext )
    {
      System.out.println("Process Picture " + finger.data);
    }
    Picture retval = new Picture(collageHeight,collageWidth);
    int i = 0;
    for( Node finger = pFirst; finger != null; finger = finger.pNext )
    {
      System.out.println("Process Picture " + finger.data);
      finger.data.compose(retval, 50*i, 50*i);
      i++;
    }
    return retval;
  }
  public void cutMiddle()
  {
    int cutIndex = nPictures-1;
    clipboard = myArray[cutIndex];
    for( int i = cutIndex; i < nPictures - 1; i++ )
    {
      myArray[i] = myArray[i + 1];
    }
    nPictures--;
  }
  public void cutEnd()
{
int cutIndex = nPictures;
clipboard = myArray[cutIndex];
for( int i = cutIndex; i<nPictures - 1; i++)
{
myArray[i] = myArray[i + 1];
}
nPictures--;
}
public void pasteEnd()
{
myArray[nPictures] = clipboard;
nPictures++;
}
  public boolean isFull()
  {
    return false;
  }
  public boolean isEmpty()
  {
    return nPictures == 0;
  }
}

import java.util.Scanner;
class LineCollageMaker
{
  public static void main(String a[])
  {
    LinearCollage myCollage;
    Scanner uiInput = new Scanner(System.in);


    myCollage = new LinearCollage();

    FileChooser.pickMediaPath();
    boolean inputting = true;
    while( inputting ) 
    {
      System.out.println("Another picture? Type Y if so.");
      String answer = uiInput.next();
      if(answer.equals("Y"))
      {
        Picture pin = new Picture(FileChooser.pickAFile());
        myCollage.addPictureAtEnd(pin);
      }
      else
      {
        inputting = false;
      }


    }
    Picture firstToShow = myCollage.makeCollage();
    firstToShow.show();
    //YOU Code the user inteface loop and dispatch to methods
    //of myCollage here..
    boolean done = false;
   while( !done )
    {
      System.out.println("MENU (CASE SENSITIVE!)");
      System.out.println("CM - cut middle and move it to the clipboard");
      System.out.println("PE - paste clipboard to end");
      System.out.println("CE - cut end and move it to clipboard");
      System.out.println("XX - stop running this program");
      String command = uiInput.next();
      if(command.equals("XX"))
        done = true;
      else if(command.equals("CM"))
      {
        if(myCollage.isEmpty())
        {
          System.out.println("Can't cut from an empty collage.");
        }
        else
        {
          myCollage.cutMiddle();
          myCollage.makeCollage().show();
        }
      }
      else if(command.equals("PE"))
      {
        if(myCollage.isFull())
        {
          System.out.println("Can't paste to an empty collage.");
        }
        else
        {
         myCollage.pasteEnd();
         myCollage.makeCollage().show();
        }
      }
        else if(command.equals("CE"))
      {
        if(myCollage.isEmpty())
        {
          System.out.println("Can't copy from an empty collage.");
        }
        else
        {
         myCollage.cutEnd();
         myCollage.makeCollage().show(); 
        }
      }
      else
        System.out.println("Unrecognized command. Try again.");
    }

  }
}



public class Node
{
  //le class variables
  private Picture myPic;
  private Node next;

  //le constructors  
  public Node(Picture heldPic)
  {
    myPic=heldPic;
    next=null;
  }

  public void setNext(Node nextOne)
  {
    this.next=nextOne;
  }
  public Node getNext()
  {
   return this.next; 
  }
  public Picture getPicture()
  {
   return this.myPic; 
  }


  //le methods
  public void drawFromMeOn(Picture bg)
  {
   Node current;
   int currentX=0, currentY=bg.getHeight()-1;

   current = this;
   while (current != null)
   {
    current.drawMeOn(bg,currentX, currentY);
    currentX = currentX + current.getPicture().getWidth();
    current=current.getNext();
   }
  }

 private void drawMeOn(Picture bg, int left, int bottom)
 {
  this.getPicture().blueScreen(bg, left, bottom-this.getPicture().getHeight());
 }
}

person Methos    schedule 03.03.2012    source источник
comment
Это вопрос домашнего задания? Если это так, пожалуйста, отметьте это как таковое.   -  person John Ericksen    schedule 03.03.2012
comment
Если вы понятия не имеете, что такое двусвязный список, почему вы хотите преобразовать эту реализацию в один?   -  person Dathan    schedule 03.03.2012
comment
Прости за это. Не знал об этом правиле.   -  person Methos    schedule 04.03.2012


Ответы (3)


Двусвязный список — это просто связанный список, в котором каждый элемент имеет как следующий, так и предыдущий элементы, указывающие на элементы до и после него, а не только на элемент после него в одном связанном списке.

поэтому, чтобы преобразовать ваш список в двусвязный список, просто измените свой узел на:

private class Node
  {
    Picture data;
    Node pNext;
    Node pPrev;
  };

и при повторении списка на каждом новом узле добавляйте ссылку на предыдущий узел.

person Not_a_Golfer    schedule 03.03.2012
comment
не забывайте, что предыдущий элемент первого элемента равен null, поэтому он является следующим элементом последнего элемента :). - person Luiggi Mendoza; 03.03.2012
comment
Как будет ссылаться на предыдущий узел на каждом новом? Также @LuiggiMendoza, я не уверен, что вы имеете в виду. - person Methos; 04.03.2012
comment
@methos, когда вы создаете новый узел, просто добавьте текущий верхний узел как предыдущий. довольно просто. - person Not_a_Golfer; 04.03.2012

Двусвязный список продвигает односвязный список на один шаг вперед, так как также имеет ссылку на предыдущий узел, а не только на следующий.

Признаюсь, меня немного смущает ваш код, так как похоже, что у вас есть частный класс для Node, а затем еще один публичный класс для него. Чтобы сделать этот список двусвязным, добавьте еще одну переменную экземпляра Node в свой класс Node, которая ссылается на предыдущий узел, а затем обновите эту переменную при добавлении новых узлов.

person christophmccann    schedule 03.03.2012
comment
У меня также такое же мнение, почему здесь требуются два класса узлов. Для этой цели подойдет один частный класс. - person AKS; 27.12.2012

Вы можете преобразовать односвязный список в двусвязный список с помощью концепции, называемой связанным списком на основе XOR. Красота таблицы истинности XOR делает ее подходящей для этого варианта использования.

Проверьте это: https://www.geeksforgeeks.org/xor-linked-list-a-memory-efficient-double-linked-list-set-1/

person Balaji Boggaram Ramanarayan    schedule 11.08.2018