Java bidirectional circular linked list implementation code

  • 2020-04-01 02:21:10
  • OfStack

Case 1:


package com.xlst.util;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class BothwayLoopLinked {

private static final Map<String, Integer> sizeMap = new HashMap<String, Integer>();

private String linkedId = null;

private Object data = null;

private BothwayLoopLinked prev = this;

private BothwayLoopLinked next = this;
public BothwayLoopLinked(){}

public void insertAfter(BothwayLoopLinked newLinked){
//The original front and back nodes
BothwayLoopLinked oldBefore = this;
BothwayLoopLinked oldAfter = this.next;
//Set the relationship between newLinked and the original predecessor node
oldBefore.next = newLinked;
newLinked.prev = oldBefore;
//Set the relationship between newLinked and the original and subsequent nodes
oldAfter.prev = newLinked;
newLinked.next = oldAfter;
//Add one to the length of the list
changeSize(+1);
//LinkedId that binds the new node
newLinked.linkedId = this.linkedId;
}

public void insertBefore(BothwayLoopLinked newLinked){
//The original front and back nodes
BothwayLoopLinked oldBefore = this.prev;
BothwayLoopLinked oldAfter = this;
//Set the relationship between newLinked and the original predecessor node
oldBefore.next = newLinked;
newLinked.prev = oldBefore;
//Set the relationship between newLinked and the original and subsequent nodes
oldAfter.prev = newLinked;
newLinked.next = oldAfter;
//Add one to the length of the list
changeSize(+1);
//LinkedId that binds the new node
newLinked.linkedId = this.linkedId;
}

public BothwayLoopLinked remove(){
return remove(this);
}

public BothwayLoopLinked remove(BothwayLoopLinked linked){
linked.prev.next = linked.next;
linked.next.prev = linked.prev;
linked.prev = linked;
linked.next = linked;
//The length of the list minus one
changeSize(-1);
//Cancel the linkedId for the node
this.linkedId = null;
//Returns the deleted node
return linked;
}

private void changeSize(){
changeSize(1);
}

private void changeSize(int value){
if(this.linkedId == null){
this.linkedId = UUID.randomUUID().toString();
sizeMap.put(linkedId, 1 + value); // sizeMap.put(linkedId, 2);
}else{
Integer size = sizeMap.get(this.linkedId);
//Integer is a reference type, and you don't have to put it back into sizeMap after you update the value
size += value;
}
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}

public int getSize() {
return (linkedId == null) ? 1 : sizeMap.get(this.linkedId);
}
public BothwayLoopLinked getPrev() {
return prev;
}
public BothwayLoopLinked getNext() {
return next;
}
}

Example 2:



public class Node<E> 
{
private E element; //Node data
private Node<E> next; //On the node
private Node<E> previous; //The node
private static int size=0; //The list is long
//The default closing point next previous is empty,
public Node()
{
this.element=null;
this.next=null;
this.previous=null;
}
private Node(E element,Node<E> next,Node<E> previous)
{
this.element=element;
this.next=next;
this.previous=previous;
}

public void addAfter(E e)
{
//Define a new node, next--> Head node; Previous -> Previous.
Node<E> newNode=new Node<E>(e,this,this.previous==null?this:this.previous);
//If the header next is empty, let it point to newNode
if(this.next==null)
{
this.next=newNode;
}
//If the previous is null, let it point to newNode
if(this.previous==null)
{
this.previous=newNode;
}
this.previous.next=newNode;
this.previous=newNode;
size++;
}

public void addBefor(E e)
{
Node<E> newNode=new Node<E>(e,this.next==null?this:this.next,this);
if(this.next==null)
{
this.next=newNode;
}
if(this.previous==null)
{
this.previous=newNode;
}
this.next.previous=newNode;
this.next=newNode;
size++;
}

public void add(E e,int index)
{
//The index of crossing the line
if(index>=size || index<0)
{
throw new IndexOutOfBoundsException("Node.get():"+index);
}
else
{
//Index> Size over 2, go the other way
if(index>size>>1)
{
Node<E> temp=this;
for(int i=size;i>index;i--)
{
temp=temp.previous;
}
Node<E> newNode=new Node<E>(e,temp,temp.previous);
temp.previous.next=newNode;
temp.previous=newNode;
}
else
{
Node<E> temp=this;
for(int i=0;i<=index;i++)
{
temp=temp.next;
}
Node<E> newNode=new Node<E>(e,temp,temp.previous);
temp.previous.next=newNode;
temp.previous=newNode;
}
size++;
}
}

public void remove(int index)
{
//The index of crossing the line
if(index>=size || index<0)
{
throw new IndexOutOfBoundsException("Node.get():"+index);
}
else
{
//Index> Size over 2, go the other way
if(index>size>>1)
{
Node<E> temp=this;
for(int i=size;i>index;i--)
{
temp=temp.previous;
}
temp.previous.next=temp.next;
temp.next.previous=temp.previous;
}
else
{
Node<E> temp=this;
for(int i=0;i<=index;i++)
{
temp=temp.next;
}
temp.previous.next=temp.next;
temp.next.previous=temp.previous;
}
size--;
}
}

public E get(int index)
{
//The index of crossing the line
if(index>=size || index<0)
{
throw new IndexOutOfBoundsException("Node.get():"+index);
}
else
{
//Index> Size over 2, go the other way
if(index>size>>1)
{
Node<E> temp=this;
for(int i=size;i>index;i--)
{
temp=temp.previous;
}
return temp.element;
}
else
{
Node<E> temp=this;
for(int i=0;i<=index;i++)
{
temp=temp.next;
}
return temp.element;
}
}
}
public int size()
{
return size;
}
public static void main(String a[])
{
Node node=new Node();
node.addAfter("1");
node.addAfter("2");
node.addAfter("3");
node.addBefor("0");
node.add("7", 0);
System.out.println(node.get(0) );
System.out.println(node.get(1) );
System.out.println(node.get(2) );
System.out.println(node.get(3) );
System.out.println(node.get(4) );
}
}

The biggest difference between the two lists is whether the head node is dummy or not, and the difference between for loop variable I when the element (get function) is taken out:

Bidirectional circular linked list (as in the design of the java.util package) : since the head is a dummy element, the element is taken from the next node of the head

One-way linked list: the head is not a dummy element, the first time must take the head node element, so on the loop and bidirectional linked list is different. That is, the first time the get doesn't go into the for loop, it just goes back to the header, and it doesn't go into the for loop until the second time


Related articles: