Design a special linked lists with Java implementation.(提示:时间复杂度都小于O(n))
Attention: Follow the instructions in the comments.
public interface LinkList {
// time complexity less than O(n)
// if value exists return true otherwise return false
boolean isExists(Integer value);
// time complexity less than O(n)
void add(Node node);
}
//------------
// Main class
//------------
public class LinkListImpl implement LinkList {
}
public class Node {
private Integer value;
// You can add fields if you need
}
//----------
// unit test
//----------
// use: Junit4
// test function which you implement
public void Test{
// function: isExists and add
}
/**
* @author hehongxia
* @since 2020年10月25日01:48:36
* @version 1.0.0
*/
public class Node {
private Integer value ;
private Node left ;
private Node right ;
private Node up ;
private Node down ;
public Node(Integer value){
this.value = value ;
}
@Override
public String toString(){
return "value is : "+ value;
}
}
LinkList
/**
* @author hehongxia
* @since 2020年10月25日01:46:36
* @version 1.0.0
*/
public interface LinkList {
/**
* time complexity less than O(n)
* @param node the new Node to add for the list
*/
void add(Node node);
/**
* get the list's size
* @return list's size
*/
Integer size();
/**
* time complexity less than O(n)
* @param value the value to find in list
* @return if value exists then return true otherwise return false
*/
Boolean isExists(Integer value);
}
LinkListImpl
import java.util.Objects;
import java.util.Random;
/**
* @author hehongxia
* @version 1.0.0
* @since 2020年10月25日02:05:55
*/
public class LinkListImpl implements LinkList {
private Integer nodeNumber;
private Integer nodeHeight;
private Node listHead;
private Node listTail;
private Random heightRandom;
public LinkListImpl() {
this.listHead = new Node(Integer.MIN_VALUE);
this.listTail = new Node(Integer.MAX_VALUE);
listHead.setRight(listTail);
listTail.setLeft(listHead);
this.nodeNumber = 0;
this.nodeHeight = 0;
this.heightRandom = new Random();
}
/**
* time complexity less than O(n)
*
* @param addNode the new Node to add for the list
*/
@Override
public void add(Node addNode) {
if(Objects.isNull(addNode) || Objects.isNull(addNode.getValue())){
throw new IllegalArgumentException("param is illegal");
}
Node preNode;
int level = 0;
preNode = findNode(addNode.getValue());
// if the node exist,just ignore or add it as a new Node to the right for the old equals node
// here, add it
if (Objects.equals(preNode.getValue(), addNode.getValue())) {
// return ;
if (Objects.nonNull(preNode.getDown())) {
while (Objects.isNull(preNode.getDown())) {
preNode = preNode.getDown();
}
}
}
// add the node
addNode.setLeft(preNode);
addNode.setRight(preNode.getRight());
preNode.getRight().setLeft(addNode);
preNode.setRight(addNode);
// update the higher node
double standard = 0.5;
int nodeHighest = 3;
boolean firstCreateLevel = true;
while (this.heightRandom.nextDouble() < standard && level < nodeHighest) {
if (level >= this.nodeHeight && firstCreateLevel) {
//Create a new empty TOP layer
addEmptyLevel();
firstCreateLevel = false;
}
while (Objects.isNull(preNode.getUp()) && Objects.nonNull(preNode.getLeft())) {
preNode = preNode.getLeft();
}
preNode = preNode.getUp();
Node addUpNode = new Node(addNode.getValue());
addUpNode.setLeft(preNode);
addUpNode.setRight(preNode.getRight());
addUpNode.setDown(addNode);
preNode.getRight().setLeft(addUpNode);
preNode.setRight(addUpNode);
addNode.setUp(addUpNode);
addNode = addUpNode;
level = level + 1;
}
this.nodeNumber = nodeNumber + 1;
}
/**
* get the list's size
*
* @return list's size
*/
@Override
public Integer size() {
return this.nodeNumber;
}
/**
* time complexity less than O(n)
*
* @param value the value to find in list
* @return if value exists then return true otherwise return false
*/
@Override
public Boolean isExists(Integer value) {
if(Objects.isNull(value)){
throw new IllegalArgumentException("param is illegal");
}
Node node = findNode(value);
// now, already find the node witch one the value not less than.
// if the two values id equal,return the node
return Objects.equals(node.getValue(), value);
}
/**
* to find a Node
*
* @param value the Node's value
* @return if the value is find out then return the Node, otherwise return null
*/
private Node findNode(Integer value) {
Node node = listHead;
while (true) {
// to find the right Node until find the first larger one or equal one
// foe example value=626, Ps: why the number is 626? aha,it's my birthday.
// 126->220->626->813->1223
// |
// node (stop find)
while (node.getRight().getValue() != Integer.MAX_VALUE && node.getRight().getValue() <= value) {
node = node.getRight();
}
if (Objects.equals(node.getValue(), value)) {
// if find it out from higher level,return it
break;
}
if (Objects.isNull(node.getDown())) {
// the search already reached the lowest level, but the value doesn't equals 626,just return null
break;
} else {
// continue to find the value in lower layer from current node's right node to the next larger
node = node.getDown();
}
}
return node;
}
/**
* to create a new higher layer
*/
private void addEmptyLevel() {
Node newLeftNode, newRightNode;
newLeftNode = new Node(Integer.MIN_VALUE);
newRightNode = new Node(Integer.MAX_VALUE);
newLeftNode.setRight(newRightNode);
newLeftNode.setDown(this.listHead);
newRightNode.setLeft(newLeftNode);
newRightNode.setDown(this.listTail);
this.listHead.setUp(newLeftNode);
this.listTail.setUp(newRightNode);
this.listHead = newLeftNode;
this.listTail = newRightNode;
this.nodeHeight = nodeHeight + 1;
}
}
unit test
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
/**
* @author hehongxia
*/
@FixMethodOrder(MethodSorters.JVM)
public class LinkListImplTest {
private LinkListImpl linkList = new LinkListImpl();
@Test
public void add() {
Node node = new Node(525);
linkList.add(node);
Assert.assertEquals("node.value=525写入异常", 1, linkList.size().longValue());
}
@Test
public void isExists() {
Node nodeOne = new Node(525);
linkList.add(nodeOne);
Assert.assertFalse(linkList.isExists(626));
Node nodeTwo = new Node(626);
linkList.add(nodeTwo);
Assert.assertTrue(linkList.isExists(626));
}
}