mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-07 17:56:02 +08:00
Fix singly linked list (#2988)
This commit is contained in:
8
pom.xml
8
pom.xml
@ -43,6 +43,14 @@
|
|||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.22.2</version>
|
<version>2.22.2</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>16</source>
|
||||||
|
<target>16</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
@ -44,16 +44,14 @@ public class SinglyLinkedList extends Node{
|
|||||||
public boolean detectLoop() {
|
public boolean detectLoop() {
|
||||||
Node currentNodeFast = head;
|
Node currentNodeFast = head;
|
||||||
Node currentNodeSlow = head;
|
Node currentNodeSlow = head;
|
||||||
boolean flag = false;
|
while (currentNodeFast != null && currentNodeFast.next != null) {
|
||||||
while (currentNodeFast != null && currentNodeFast.next != null && currentNodeSlow != null && currentNodeSlow.next != null) {
|
|
||||||
currentNodeFast = currentNodeFast.next.next;
|
currentNodeFast = currentNodeFast.next.next;
|
||||||
currentNodeSlow = currentNodeSlow.next;
|
currentNodeSlow = currentNodeSlow.next;
|
||||||
if (currentNodeFast == currentNodeSlow) {
|
if (currentNodeFast == currentNodeSlow) {
|
||||||
flag = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flag;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,6 +107,10 @@ public class SinglyLinkedList extends Node{
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Node reverseList(Node node) {
|
Node reverseList(Node node) {
|
||||||
|
Node prevNode = head;
|
||||||
|
while(prevNode.next!=node){
|
||||||
|
prevNode = prevNode.next;
|
||||||
|
}
|
||||||
Node prev = null, curr = node, next;
|
Node prev = null, curr = node, next;
|
||||||
while (curr != null) {
|
while (curr != null) {
|
||||||
next = curr.next;
|
next = curr.next;
|
||||||
@ -116,8 +118,8 @@ public class SinglyLinkedList extends Node{
|
|||||||
prev = curr;
|
prev = curr;
|
||||||
curr = next;
|
curr = next;
|
||||||
}
|
}
|
||||||
node = prev;
|
prevNode.next = prev;
|
||||||
return node;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -161,6 +163,14 @@ public class SinglyLinkedList extends Node{
|
|||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set head of the list.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void setHead(Node head) {
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the count of the list manually
|
* Calculate the count of the list manually
|
||||||
*
|
*
|
||||||
@ -205,138 +215,33 @@ public class SinglyLinkedList extends Node{
|
|||||||
return joiner.toString();
|
return joiner.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void deleteDuplicates() {
|
||||||
* Driver Code
|
|
||||||
*/
|
|
||||||
public static void main(String[] arg) {
|
|
||||||
SinglyLinkedList list = new SinglyLinkedList();
|
|
||||||
assert list.isEmpty();
|
|
||||||
assert list.size() == 0 && list.count() == 0;
|
|
||||||
assert list.toString().equals("");
|
|
||||||
|
|
||||||
/* Test insert function */
|
Node pred = head;
|
||||||
list.insertHead(5);
|
// predecessor = the node
|
||||||
list.insertHead(7);
|
// having sublist of its duplicates
|
||||||
list.insertHead(10);
|
Node newHead = head;
|
||||||
list.insert(3);
|
while (newHead != null) {
|
||||||
list.insertNth(1, 4);
|
|
||||||
assert list.toString().equals("10->7->5->3->1");
|
|
||||||
|
|
||||||
/* Test search function */
|
|
||||||
assert list.search(10) && list.search(5) && list.search(1) && !list.search(100);
|
|
||||||
|
|
||||||
/* Test get function */
|
|
||||||
assert list.getNth(0) == 10 && list.getNth(2) == 5 && list.getNth(4) == 1;
|
|
||||||
|
|
||||||
/* Test delete function */
|
|
||||||
list.deleteHead();
|
|
||||||
list.deleteNth(1);
|
|
||||||
list.delete();
|
|
||||||
assert list.toString().equals("7->3");
|
|
||||||
|
|
||||||
assert list.size == 2 && list.size() == list.count();
|
|
||||||
|
|
||||||
list.clear();
|
|
||||||
assert list.isEmpty();
|
|
||||||
|
|
||||||
try {
|
|
||||||
list.delete();
|
|
||||||
assert false;
|
|
||||||
/* this should not happen */
|
|
||||||
} catch (Exception e) {
|
|
||||||
assert true;
|
|
||||||
/* this should happen */
|
|
||||||
}
|
|
||||||
|
|
||||||
Node instance = new Node();
|
|
||||||
Node head = new Node(0, new Node(2, new Node(3, new Node(3, new Node(4)))));
|
|
||||||
head = instance.deleteDuplicates(head);
|
|
||||||
instance.print(head);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is the nodes of the SinglyLinked List. They consist of a value and
|
|
||||||
* a pointer to the node after them.
|
|
||||||
*/
|
|
||||||
class Node {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Head refer to the front of the list
|
|
||||||
*/
|
|
||||||
public Node head;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Size of SinglyLinkedList
|
|
||||||
*/
|
|
||||||
public int size;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the node
|
|
||||||
*/
|
|
||||||
int value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Point to the next node
|
|
||||||
*/
|
|
||||||
Node next;
|
|
||||||
|
|
||||||
Node() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param value Value to be put in the node
|
|
||||||
*/
|
|
||||||
Node(int value) {
|
|
||||||
this(value, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param value Value to be put in the node
|
|
||||||
* @param next Reference to the next node
|
|
||||||
*/
|
|
||||||
Node(int value, Node next) {
|
|
||||||
this.value = value;
|
|
||||||
this.next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node deleteDuplicates(Node head) {
|
|
||||||
// sentinel
|
|
||||||
Node sentinel = new Node(0, head);
|
|
||||||
|
|
||||||
// predecessor = the last node
|
|
||||||
// before the sublist of duplicates
|
|
||||||
Node pred = sentinel;
|
|
||||||
|
|
||||||
while (head != null) {
|
|
||||||
// if it's a beginning of duplicates sublist
|
// if it's a beginning of duplicates sublist
|
||||||
// skip all duplicates
|
// skip all duplicates
|
||||||
if (head.next != null && head.value == head.next.value) {
|
if (newHead.next != null && newHead.value == newHead.next.value) {
|
||||||
// move till the end of duplicates sublist
|
// move till the end of duplicates sublist
|
||||||
while (head.next != null && head.value == head.next.value) {
|
while (newHead.next != null && newHead.value == newHead.next.value) {
|
||||||
head = head.next;
|
newHead = newHead.next;
|
||||||
}
|
}
|
||||||
// skip all duplicates
|
// skip all duplicates
|
||||||
pred.next = head.next;
|
pred.next = newHead.next;
|
||||||
|
newHead = null;
|
||||||
|
|
||||||
// otherwise, move predecessor
|
// otherwise, move predecessor
|
||||||
} else {
|
|
||||||
pred = pred.next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// move forward
|
// move forward
|
||||||
head = head.next;
|
pred = pred.next;
|
||||||
|
newHead = pred;
|
||||||
}
|
}
|
||||||
return sentinel.next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void print(Node head) {
|
public void print() {
|
||||||
Node temp = head;
|
Node temp = head;
|
||||||
while (temp != null && temp.next != null) {
|
while (temp != null && temp.next != null) {
|
||||||
System.out.print(temp.value + "->");
|
System.out.print(temp.value + "->");
|
||||||
@ -344,6 +249,7 @@ class Node {
|
|||||||
}
|
}
|
||||||
if (temp != null) {
|
if (temp != null) {
|
||||||
System.out.print(temp.value);
|
System.out.print(temp.value);
|
||||||
|
System.out.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,13 +285,15 @@ class Node {
|
|||||||
head = newNode;
|
head = newNode;
|
||||||
size++;
|
size++;
|
||||||
return;
|
return;
|
||||||
} else if (position == 0) {
|
}
|
||||||
|
if (position == 0) {
|
||||||
/* insert at the head of the list */
|
/* insert at the head of the list */
|
||||||
newNode.next = head;
|
newNode.next = head;
|
||||||
head = newNode;
|
head = newNode;
|
||||||
size++;
|
size++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node cur = head;
|
Node cur = head;
|
||||||
for (int i = 0; i < position - 1; ++i) {
|
for (int i = 0; i < position - 1; ++i) {
|
||||||
cur = cur.next;
|
cur = cur.next;
|
||||||
@ -393,25 +301,13 @@ class Node {
|
|||||||
newNode.next = cur.next;
|
newNode.next = cur.next;
|
||||||
cur.next = newNode;
|
cur.next = newNode;
|
||||||
size++;
|
size++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Swaps nodes of two given values a and b.
|
* Swaps nodes of two given values a and b.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void swapNodes(int a, int b) {
|
|
||||||
Node currentNode = head;
|
|
||||||
Node temp = null;
|
|
||||||
while (currentNode != null) {
|
|
||||||
if (currentNode.next.value == a) {
|
|
||||||
temp = currentNode.next;
|
|
||||||
}
|
|
||||||
if (currentNode.next.value == b) {
|
|
||||||
currentNode.next = temp;
|
|
||||||
}
|
|
||||||
currentNode = currentNode.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a node at the head
|
* Deletes a node at the head
|
||||||
@ -479,4 +375,96 @@ class Node {
|
|||||||
throw new IndexOutOfBoundsException(position + "");
|
throw new IndexOutOfBoundsException(position + "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Driver Code
|
||||||
|
*/
|
||||||
|
public static void main(String[] arg) {
|
||||||
|
SinglyLinkedList list = new SinglyLinkedList();
|
||||||
|
assert list.isEmpty();
|
||||||
|
assert list.size() == 0 && list.count() == 0;
|
||||||
|
assert list.toString().equals("");
|
||||||
|
|
||||||
|
/* Test insert function */
|
||||||
|
list.insertHead(5);
|
||||||
|
list.insertHead(7);
|
||||||
|
list.insertHead(10);
|
||||||
|
list.insert(3);
|
||||||
|
list.insertNth(1, 4);
|
||||||
|
assert list.toString().equals("10->7->5->3->1");
|
||||||
|
System.out.println(list.toString());
|
||||||
|
/* Test search function */
|
||||||
|
assert list.search(10) && list.search(5) && list.search(1) && !list.search(100);
|
||||||
|
|
||||||
|
/* Test get function */
|
||||||
|
assert list.getNth(0) == 10 && list.getNth(2) == 5 && list.getNth(4) == 1;
|
||||||
|
|
||||||
|
/* Test delete function */
|
||||||
|
list.deleteHead();
|
||||||
|
list.deleteNth(1);
|
||||||
|
list.delete();
|
||||||
|
assert list.toString().equals("7->3");
|
||||||
|
System.out.println(list.toString());
|
||||||
|
assert list.size == 2 && list.size() == list.count();
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
assert list.isEmpty();
|
||||||
|
|
||||||
|
try {
|
||||||
|
list.delete();
|
||||||
|
assert false;
|
||||||
|
/* this should not happen */
|
||||||
|
} catch (Exception e) {
|
||||||
|
assert true;
|
||||||
|
/* this should happen */
|
||||||
|
}
|
||||||
|
|
||||||
|
SinglyLinkedList instance = new SinglyLinkedList();
|
||||||
|
Node head = new Node(0, new Node(2, new Node(3, new Node(3, new Node(4)))));
|
||||||
|
instance.setHead(head);
|
||||||
|
instance.deleteDuplicates();
|
||||||
|
instance.print();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is the nodes of the SinglyLinked List. They consist of a value and
|
||||||
|
* a pointer to the node after them.
|
||||||
|
*/
|
||||||
|
class Node {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of the node
|
||||||
|
*/
|
||||||
|
int value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Point to the next node
|
||||||
|
*/
|
||||||
|
Node next;
|
||||||
|
|
||||||
|
Node() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param value Value to be put in the node
|
||||||
|
*/
|
||||||
|
Node(int value) {
|
||||||
|
this(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param value Value to be put in the node
|
||||||
|
* @param next Reference to the next node
|
||||||
|
*/
|
||||||
|
Node(int value, Node next) {
|
||||||
|
this.value = value;
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user