mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-07 01:35:16 +08:00
Refactor to remove code smells (#2982)
Co-authored-by: Rushi <rs397441@dal.ca>
This commit is contained in:
@ -12,7 +12,7 @@ import java.util.Scanner;
|
||||
*/
|
||||
public class HillCipher {
|
||||
|
||||
static Scanner in = new Scanner(System.in);
|
||||
static Scanner userInput = new Scanner(System.in);
|
||||
|
||||
/* Following function encrypts the message
|
||||
*/
|
||||
@ -20,26 +20,23 @@ public class HillCipher {
|
||||
message = message.toUpperCase();
|
||||
// Get key matrix
|
||||
System.out.println("Enter key matrix size");
|
||||
int n = in.nextInt();
|
||||
int matrixSize = userInput.nextInt();
|
||||
System.out.println("Enter Key/encryptionKey matrix ");
|
||||
int keyMatrix[][] = new int[n][n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
keyMatrix[i][j] = in.nextInt();
|
||||
int keyMatrix[][] = new int[matrixSize][matrixSize];
|
||||
for (int i = 0; i < matrixSize; i++) {
|
||||
for (int j = 0; j < matrixSize; j++) {
|
||||
keyMatrix[i][j] = userInput.nextInt();
|
||||
}
|
||||
}
|
||||
//check if det = 0
|
||||
if (determinant(keyMatrix, n) % 26 == 0) {
|
||||
System.out.println("Invalid key, as determinant = 0. Program Terminated");
|
||||
return;
|
||||
}
|
||||
validateDeterminant(keyMatrix,matrixSize);
|
||||
|
||||
int[][] messageVector = new int[n][1];
|
||||
int[][] messageVector = new int[matrixSize][1];
|
||||
String CipherText = "";
|
||||
int cipherMatrix[][] = new int[n][1];
|
||||
int cipherMatrix[][] = new int[matrixSize][1];
|
||||
int j = 0;
|
||||
while (j < message.length()) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int i = 0; i < matrixSize; i++) {
|
||||
if (j >= message.length()) {
|
||||
messageVector[i][0] = 23;
|
||||
} else {
|
||||
@ -49,16 +46,16 @@ public class HillCipher {
|
||||
j++;
|
||||
}
|
||||
int x, i;
|
||||
for (i = 0; i < n; i++) {
|
||||
for (i = 0; i < matrixSize; i++) {
|
||||
cipherMatrix[i][0] = 0;
|
||||
|
||||
for (x = 0; x < n; x++) {
|
||||
for (x = 0; x < matrixSize; x++) {
|
||||
cipherMatrix[i][0] += keyMatrix[i][x] * messageVector[x][0];
|
||||
}
|
||||
System.out.println(cipherMatrix[i][0]);
|
||||
cipherMatrix[i][0] = cipherMatrix[i][0] % 26;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
for (i = 0; i < matrixSize; i++) {
|
||||
CipherText += (char) (cipherMatrix[i][0] + 65);
|
||||
}
|
||||
}
|
||||
@ -70,19 +67,17 @@ public class HillCipher {
|
||||
message = message.toUpperCase();
|
||||
// Get key matrix
|
||||
System.out.println("Enter key matrix size");
|
||||
int n = in.nextInt();
|
||||
int n = userInput.nextInt();
|
||||
System.out.println("Enter inverseKey/decryptionKey matrix ");
|
||||
int keyMatrix[][] = new int[n][n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
keyMatrix[i][j] = in.nextInt();
|
||||
keyMatrix[i][j] = userInput.nextInt();
|
||||
}
|
||||
}
|
||||
//check if det = 0
|
||||
if (determinant(keyMatrix, n) % 26 == 0) {
|
||||
System.out.println("Invalid key, as determinant = 0. Program Terminated");
|
||||
return;
|
||||
}
|
||||
validateDeterminant(keyMatrix,n);
|
||||
|
||||
//solving for the required plaintext message
|
||||
int[][] messageVector = new int[n][1];
|
||||
String PlainText = "";
|
||||
@ -145,12 +140,12 @@ public class HillCipher {
|
||||
}
|
||||
|
||||
// Function to implement Hill Cipher
|
||||
static void hillcipher(String message) {
|
||||
static void hillCipher(String message) {
|
||||
message.toUpperCase();
|
||||
System.out.println("What do you want to process from the message?");
|
||||
System.out.println("Press 1: To Encrypt");
|
||||
System.out.println("Press 2: To Decrypt");
|
||||
short sc = in.nextShort();
|
||||
short sc = userInput.nextShort();
|
||||
if (sc == 1) {
|
||||
encrypt(message);
|
||||
} else if (sc == 2) {
|
||||
@ -160,11 +155,18 @@ public class HillCipher {
|
||||
}
|
||||
}
|
||||
|
||||
static void validateDeterminant(int[][] keyMatrix, int n){
|
||||
if (determinant(keyMatrix, n) % 26 == 0) {
|
||||
System.out.println("Invalid key, as determinant = 0. Program Terminated");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Driver code
|
||||
public static void main(String[] args) {
|
||||
// Get the message to be encrypted
|
||||
System.out.println("Enter message");
|
||||
String message = in.nextLine();
|
||||
hillcipher(message);
|
||||
String message = userInput.nextLine();
|
||||
hillCipher(message);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,11 +18,15 @@ public class DoublyLinkedList {
|
||||
/**
|
||||
* Head refers to the front of the list
|
||||
*/
|
||||
private Link head;
|
||||
protected Link head;
|
||||
/**
|
||||
* Tail refers to the back of the list
|
||||
*/
|
||||
private Link tail;
|
||||
/**
|
||||
* Link Operations to perform operations on nodes of the list
|
||||
*/
|
||||
private LinkOperations linkOperations;
|
||||
|
||||
/**
|
||||
* Size refers to the number of elements present in the list
|
||||
@ -49,19 +53,152 @@ public class DoublyLinkedList {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
for (int i : array) {
|
||||
insertTail(i);
|
||||
linkOperations.insertTail(i,this);
|
||||
}
|
||||
size = array.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if list is empty
|
||||
*
|
||||
* @return true if list is empty
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return (head == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints contents of the list
|
||||
*/
|
||||
public void display() { // Prints contents of the list
|
||||
Link current = head;
|
||||
while (current != null) {
|
||||
current.displayLink();
|
||||
current = current.next;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the contents of the list in reverse order
|
||||
*/
|
||||
public void displayBackwards() {
|
||||
Link current = tail;
|
||||
while (current != null) {
|
||||
current.displayLink();
|
||||
current = current.previous;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used to implement the nodes of the linked list.
|
||||
*
|
||||
* @author Unknown
|
||||
*/
|
||||
class Link {
|
||||
|
||||
/**
|
||||
* Value of node
|
||||
*/
|
||||
public int value;
|
||||
/**
|
||||
* This points to the link in front of the new link
|
||||
*/
|
||||
public Link next;
|
||||
/**
|
||||
* This points to the link behind the new link
|
||||
*/
|
||||
public Link previous;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param value Value of node
|
||||
*/
|
||||
public Link(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the node
|
||||
*/
|
||||
public void displayLink() {
|
||||
System.out.print(value + " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Main Method
|
||||
*
|
||||
* @param args Command line arguments
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
DoublyLinkedList myList = new DoublyLinkedList();
|
||||
LinkOperations linkOperations = new LinkOperations();
|
||||
linkOperations.insertHead(13,myList);
|
||||
linkOperations.insertHead(7,myList);
|
||||
linkOperations.insertHead(10,myList);
|
||||
myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) -->
|
||||
myList.displayBackwards();
|
||||
|
||||
linkOperations.insertTail(11,myList);
|
||||
myList.display(); // <-- 10(head) <--> 7 <--> 13 <--> 11(tail) -->
|
||||
myList.displayBackwards();
|
||||
|
||||
linkOperations.deleteTail();
|
||||
myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) -->
|
||||
myList.displayBackwards();
|
||||
|
||||
linkOperations.delete(7);
|
||||
myList.display(); // <-- 10(head) <--> 13(tail) -->
|
||||
myList.displayBackwards();
|
||||
|
||||
linkOperations.insertOrdered(23,myList);
|
||||
linkOperations.insertOrdered(67,myList);
|
||||
linkOperations.insertOrdered(3,myList);
|
||||
myList.display(); // <-- 3(head) <--> 10 <--> 13 <--> 23 <--> 67(tail) -->
|
||||
linkOperations.insertElementByIndex(5, 1,myList);
|
||||
myList.display(); // <-- 3(head) <--> 5 <--> 10 <--> 13 <--> 23 <--> 67(tail) -->
|
||||
myList.displayBackwards();
|
||||
linkOperations.reverse(); // <-- 67(head) <--> 23 <--> 13 <--> 10 <--> 5 <--> 3(tail) -->
|
||||
myList.display();
|
||||
|
||||
linkOperations.clearList();
|
||||
myList.display();
|
||||
myList.displayBackwards();
|
||||
linkOperations.insertHead(20,myList);
|
||||
myList.display();
|
||||
myList.displayBackwards();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This class implements the operations of the Link nodes.
|
||||
*/
|
||||
class LinkOperations{
|
||||
/**
|
||||
* Head refers to the front of the list
|
||||
*/
|
||||
private Link head;
|
||||
/**
|
||||
* Tail refers to the back of the list
|
||||
*/
|
||||
private Link tail;
|
||||
|
||||
/**
|
||||
* Size refers to the number of elements present in the list
|
||||
*/
|
||||
private int size;
|
||||
|
||||
/**
|
||||
* Insert an element at the head
|
||||
*
|
||||
* @param x Element to be inserted
|
||||
*/
|
||||
public void insertHead(int x) {
|
||||
public void insertHead(int x,DoublyLinkedList doublyLinkedList) {
|
||||
Link newLink = new Link(x); // Create a new link with a value attached to it
|
||||
if (isEmpty()) // Set the first element added to be the tail
|
||||
if (doublyLinkedList.isEmpty()) // Set the first element added to be the tail
|
||||
{
|
||||
tail = newLink;
|
||||
} else {
|
||||
@ -77,10 +214,10 @@ public class DoublyLinkedList {
|
||||
*
|
||||
* @param x Element to be inserted
|
||||
*/
|
||||
public void insertTail(int x) {
|
||||
public void insertTail(int x,DoublyLinkedList doublyLinkedList) {
|
||||
Link newLink = new Link(x);
|
||||
newLink.next = null; // currentTail(tail) newlink -->
|
||||
if (isEmpty()) { // Check if there are no elements in list then it adds first element
|
||||
if (doublyLinkedList.isEmpty()) { // Check if there are no elements in list then it adds first element
|
||||
tail = newLink;
|
||||
head = tail;
|
||||
} else {
|
||||
@ -97,15 +234,15 @@ public class DoublyLinkedList {
|
||||
* @param x Element to be inserted
|
||||
* @param index Index(from start) at which the element x to be inserted
|
||||
*/
|
||||
public void insertElementByIndex(int x, int index) {
|
||||
public void insertElementByIndex(int x, int index,DoublyLinkedList doublyLinkedList) {
|
||||
if (index > size) {
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
||||
}
|
||||
if (index == 0) {
|
||||
insertHead(x);
|
||||
insertHead(x,doublyLinkedList);
|
||||
} else {
|
||||
if (index == size) {
|
||||
insertTail(x);
|
||||
insertTail(x,doublyLinkedList);
|
||||
} else {
|
||||
Link newLink = new Link(x);
|
||||
Link previousLink = head; //
|
||||
@ -192,7 +329,7 @@ public class DoublyLinkedList {
|
||||
*
|
||||
* @param x Element to be added
|
||||
*/
|
||||
public void insertOrdered(int x) {
|
||||
public void insertOrdered(int x,DoublyLinkedList doublyLinkedList) {
|
||||
Link newLink = new Link(x);
|
||||
Link current = head;
|
||||
while (current != null && x > current.value) // Find the position to insert
|
||||
@ -201,9 +338,9 @@ public class DoublyLinkedList {
|
||||
}
|
||||
|
||||
if (current == head) {
|
||||
insertHead(x);
|
||||
insertHead(x,doublyLinkedList);
|
||||
} else if (current == null) {
|
||||
insertTail(x);
|
||||
insertTail(x,doublyLinkedList);
|
||||
} else { // Before: 1 <--> 2(current) <--> 3
|
||||
newLink.previous = current.previous; // 1 <-- newLink
|
||||
current.previous.next = newLink; // 1 <--> newLink
|
||||
@ -230,14 +367,14 @@ public class DoublyLinkedList {
|
||||
--size;
|
||||
}
|
||||
|
||||
public static void removeDuplicates(DoublyLinkedList l) {
|
||||
public void removeDuplicates(DoublyLinkedList l) {
|
||||
Link linkOne = l.head;
|
||||
while (linkOne.next != null) { // list is present
|
||||
Link linkTwo = linkOne.next; // second link for comparison
|
||||
while (linkTwo.next != null) {
|
||||
if (linkOne.value == linkTwo.value) // if there are duplicates values then
|
||||
{
|
||||
l.delete(linkTwo.value); // delete the link
|
||||
delete(linkTwo.value); // delete the link
|
||||
}
|
||||
linkTwo = linkTwo.next; // go to next link
|
||||
}
|
||||
@ -247,8 +384,6 @@ public class DoublyLinkedList {
|
||||
|
||||
/**
|
||||
* Reverses the list in place
|
||||
*
|
||||
* @param l the DoublyLinkedList to reverse
|
||||
*/
|
||||
public void reverse() {
|
||||
// Keep references to the head and tail
|
||||
@ -282,116 +417,4 @@ public class DoublyLinkedList {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if list is empty
|
||||
*
|
||||
* @return true if list is empty
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return (head == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints contents of the list
|
||||
*/
|
||||
public void display() { // Prints contents of the list
|
||||
Link current = head;
|
||||
while (current != null) {
|
||||
current.displayLink();
|
||||
current = current.next;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the contents of the list in reverse order
|
||||
*/
|
||||
public void displayBackwards() {
|
||||
Link current = tail;
|
||||
while (current != null) {
|
||||
current.displayLink();
|
||||
current = current.previous;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used to implement the nodes of the linked list.
|
||||
*
|
||||
* @author Unknown
|
||||
*/
|
||||
class Link {
|
||||
|
||||
/**
|
||||
* Value of node
|
||||
*/
|
||||
public int value;
|
||||
/**
|
||||
* This points to the link in front of the new link
|
||||
*/
|
||||
public Link next;
|
||||
/**
|
||||
* This points to the link behind the new link
|
||||
*/
|
||||
public Link previous;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param value Value of node
|
||||
*/
|
||||
public Link(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the node
|
||||
*/
|
||||
public void displayLink() {
|
||||
System.out.print(value + " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Main Method
|
||||
*
|
||||
* @param args Command line arguments
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
DoublyLinkedList myList = new DoublyLinkedList();
|
||||
myList.insertHead(13);
|
||||
myList.insertHead(7);
|
||||
myList.insertHead(10);
|
||||
myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) -->
|
||||
myList.displayBackwards();
|
||||
|
||||
myList.insertTail(11);
|
||||
myList.display(); // <-- 10(head) <--> 7 <--> 13 <--> 11(tail) -->
|
||||
myList.displayBackwards();
|
||||
|
||||
myList.deleteTail();
|
||||
myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) -->
|
||||
myList.displayBackwards();
|
||||
|
||||
myList.delete(7);
|
||||
myList.display(); // <-- 10(head) <--> 13(tail) -->
|
||||
myList.displayBackwards();
|
||||
|
||||
myList.insertOrdered(23);
|
||||
myList.insertOrdered(67);
|
||||
myList.insertOrdered(3);
|
||||
myList.display(); // <-- 3(head) <--> 10 <--> 13 <--> 23 <--> 67(tail) -->
|
||||
myList.insertElementByIndex(5, 1);
|
||||
myList.display(); // <-- 3(head) <--> 5 <--> 10 <--> 13 <--> 23 <--> 67(tail) -->
|
||||
myList.displayBackwards();
|
||||
myList.reverse(); // <-- 67(head) <--> 23 <--> 13 <--> 10 <--> 5 <--> 3(tail) -->
|
||||
myList.display();
|
||||
|
||||
myList.clearList();
|
||||
myList.display();
|
||||
myList.displayBackwards();
|
||||
myList.insertHead(20);
|
||||
myList.display();
|
||||
myList.displayBackwards();
|
||||
}
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
package com.thealgorithms.datastructures.lists;
|
||||
|
||||
public class RemoveDuplicateNodes {
|
||||
|
||||
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
|
||||
// skip all duplicates
|
||||
if (head.next != null && head.value == head.next.value) {
|
||||
// move till the end of duplicates sublist
|
||||
while (head.next != null && head.value == head.next.value) {
|
||||
head = head.next;
|
||||
}
|
||||
// skip all duplicates
|
||||
pred.next = head.next;
|
||||
// otherwise, move predecessor
|
||||
} else {
|
||||
pred = pred.next;
|
||||
}
|
||||
|
||||
// move forward
|
||||
head = head.next;
|
||||
}
|
||||
return sentinel.next;
|
||||
}
|
||||
|
||||
public void print(Node head) {
|
||||
Node temp = head;
|
||||
while (temp != null && temp.next != null) {
|
||||
System.out.print(temp.value + "->");
|
||||
temp = temp.next;
|
||||
}
|
||||
if (temp != null) {
|
||||
System.out.print(temp.value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String arg[]) {
|
||||
RemoveDuplicateNodes instance = new RemoveDuplicateNodes();
|
||||
Node head = new Node(0, new Node(2, new Node(3, new Node(3, new Node(4)))));
|
||||
head = instance.deleteDuplicates(head);
|
||||
instance.print(head);
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import java.util.StringJoiner;
|
||||
/**
|
||||
* https://en.wikipedia.org/wiki/Linked_list
|
||||
*/
|
||||
public class SinglyLinkedList {
|
||||
public class SinglyLinkedList extends Node{
|
||||
|
||||
/**
|
||||
* Head refer to the front of the list
|
||||
@ -36,58 +36,10 @@ public class SinglyLinkedList {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an element at the head of the list
|
||||
*
|
||||
* @param x element to be added
|
||||
*/
|
||||
public void insertHead(int x) {
|
||||
insertNth(x, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an element at the tail of the list
|
||||
*
|
||||
* @param data element to be added
|
||||
*/
|
||||
public void insert(int data) {
|
||||
insertNth(data, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new node at a specified position of the list
|
||||
*
|
||||
* @param data data to be stored in a new node
|
||||
* @param position position at which a new node is to be inserted
|
||||
*/
|
||||
public void insertNth(int data, int position) {
|
||||
checkBounds(position, 0, size);
|
||||
Node newNode = new Node(data);
|
||||
if (head == null) {
|
||||
/* the list is empty */
|
||||
head = newNode;
|
||||
size++;
|
||||
return;
|
||||
} else if (position == 0) {
|
||||
/* insert at the head of the list */
|
||||
newNode.next = head;
|
||||
head = newNode;
|
||||
size++;
|
||||
return;
|
||||
}
|
||||
Node cur = head;
|
||||
for (int i = 0; i < position - 1; ++i) {
|
||||
cur = cur.next;
|
||||
}
|
||||
newNode.next = cur.next;
|
||||
cur.next = newNode;
|
||||
size++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if there is a loop in the singly linked list using floy'd turtle
|
||||
* and hare algorithm.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public boolean detectLoop() {
|
||||
Node currentNodeFast = head;
|
||||
@ -104,27 +56,9 @@ public class SinglyLinkedList {
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse a singly linked list from a given node till the end
|
||||
*
|
||||
*
|
||||
*/
|
||||
Node reverseList(Node node) {
|
||||
Node prev = null, curr = node, next;
|
||||
@ -138,58 +72,6 @@ public class SinglyLinkedList {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a node at the head
|
||||
*/
|
||||
public void deleteHead() {
|
||||
deleteNth(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an element at the tail
|
||||
*/
|
||||
public void delete() {
|
||||
deleteNth(size - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an element at Nth position
|
||||
*/
|
||||
public void deleteNth(int position) {
|
||||
checkBounds(position, 0, size - 1);
|
||||
if (position == 0) {
|
||||
Node destroy = head;
|
||||
head = head.next;
|
||||
destroy = null;
|
||||
/* clear to let GC do its work */
|
||||
size--;
|
||||
return;
|
||||
}
|
||||
Node cur = head;
|
||||
for (int i = 0; i < position - 1; ++i) {
|
||||
cur = cur.next;
|
||||
}
|
||||
|
||||
Node destroy = cur.next;
|
||||
cur.next = cur.next.next;
|
||||
destroy = null; // clear to let GC do its work
|
||||
|
||||
size--;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position to check position
|
||||
* @param low low index
|
||||
* @param high high index
|
||||
* @throws IndexOutOfBoundsException if {@code position} not in range
|
||||
* {@code low} to {@code high}
|
||||
*/
|
||||
public void checkBounds(int position, int low, int high) {
|
||||
if (position > high || position < low) {
|
||||
throw new IndexOutOfBoundsException(position + "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all nodes in the list
|
||||
*/
|
||||
@ -264,21 +146,6 @@ public class SinglyLinkedList {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return element at special index.
|
||||
*
|
||||
* @param index given index of element
|
||||
* @return element at special index.
|
||||
*/
|
||||
public int getNth(int index) {
|
||||
checkBounds(index, 0, size - 1);
|
||||
Node cur = head;
|
||||
for (int i = 0; i < index; ++i) {
|
||||
cur = cur.next;
|
||||
}
|
||||
return cur.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringJoiner joiner = new StringJoiner("->");
|
||||
@ -332,6 +199,12 @@ public class SinglyLinkedList {
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,6 +214,18 @@ public class SinglyLinkedList {
|
||||
*/
|
||||
class Node {
|
||||
|
||||
/**
|
||||
* Head refer to the front of the list
|
||||
*/
|
||||
public Node head;
|
||||
|
||||
/**
|
||||
* Size of SinglyLinkedList
|
||||
*/
|
||||
public int size;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The value of the node
|
||||
*/
|
||||
@ -373,4 +258,177 @@ class Node {
|
||||
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
|
||||
// skip all duplicates
|
||||
if (head.next != null && head.value == head.next.value) {
|
||||
// move till the end of duplicates sublist
|
||||
while (head.next != null && head.value == head.next.value) {
|
||||
head = head.next;
|
||||
}
|
||||
// skip all duplicates
|
||||
pred.next = head.next;
|
||||
// otherwise, move predecessor
|
||||
} else {
|
||||
pred = pred.next;
|
||||
}
|
||||
|
||||
// move forward
|
||||
head = head.next;
|
||||
}
|
||||
return sentinel.next;
|
||||
}
|
||||
|
||||
public void print(Node head) {
|
||||
Node temp = head;
|
||||
while (temp != null && temp.next != null) {
|
||||
System.out.print(temp.value + "->");
|
||||
temp = temp.next;
|
||||
}
|
||||
if (temp != null) {
|
||||
System.out.print(temp.value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an element at the head of the list
|
||||
*
|
||||
* @param x element to be added
|
||||
*/
|
||||
public void insertHead(int x) {
|
||||
insertNth(x, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an element at the tail of the list
|
||||
*
|
||||
* @param data element to be added
|
||||
*/
|
||||
public void insert(int data) {
|
||||
insertNth(data, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new node at a specified position of the list
|
||||
*
|
||||
* @param data data to be stored in a new node
|
||||
* @param position position at which a new node is to be inserted
|
||||
*/
|
||||
public void insertNth(int data, int position) {
|
||||
checkBounds(position, 0, size);
|
||||
Node newNode = new Node(data);
|
||||
if (head == null) {
|
||||
/* the list is empty */
|
||||
head = newNode;
|
||||
size++;
|
||||
return;
|
||||
} else if (position == 0) {
|
||||
/* insert at the head of the list */
|
||||
newNode.next = head;
|
||||
head = newNode;
|
||||
size++;
|
||||
return;
|
||||
}
|
||||
Node cur = head;
|
||||
for (int i = 0; i < position - 1; ++i) {
|
||||
cur = cur.next;
|
||||
}
|
||||
newNode.next = cur.next;
|
||||
cur.next = newNode;
|
||||
size++;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public void deleteHead() {
|
||||
deleteNth(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an element at the tail
|
||||
*/
|
||||
public void delete() {
|
||||
deleteNth(size - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an element at Nth position
|
||||
*/
|
||||
public void deleteNth(int position) {
|
||||
checkBounds(position, 0, size - 1);
|
||||
if (position == 0) {
|
||||
Node destroy = head;
|
||||
head = head.next;
|
||||
destroy = null;
|
||||
/* clear to let GC do its work */
|
||||
size--;
|
||||
return;
|
||||
}
|
||||
Node cur = head;
|
||||
for (int i = 0; i < position - 1; ++i) {
|
||||
cur = cur.next;
|
||||
}
|
||||
|
||||
Node destroy = cur.next;
|
||||
cur.next = cur.next.next;
|
||||
destroy = null; // clear to let GC do its work
|
||||
|
||||
size--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return element at special index.
|
||||
*
|
||||
* @param index given index of element
|
||||
* @return element at special index.
|
||||
*/
|
||||
public int getNth(int index) {
|
||||
checkBounds(index, 0, size - 1);
|
||||
Node cur = head;
|
||||
for (int i = 0; i < index; ++i) {
|
||||
cur = cur.next;
|
||||
}
|
||||
return cur.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position to check position
|
||||
* @param low low index
|
||||
* @param high high index
|
||||
* @throws IndexOutOfBoundsException if {@code position} not in range
|
||||
* {@code low} to {@code high}
|
||||
*/
|
||||
public void checkBounds(int position, int low, int high) {
|
||||
if (position > high || position < low) {
|
||||
throw new IndexOutOfBoundsException(position + "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user