From 307549ca93be8948751eaca399d8431fd2ae0552 Mon Sep 17 00:00:00 2001 From: Peng Yue Date: Wed, 3 Jan 2018 18:12:35 +0000 Subject: [PATCH] 1. Double link list implementation 2. Find nth node from the end of the single link list 3. Loop detection in the single link list --- .../FindNodeEfficient.java | 54 ++++++ .../FindNodeHashTable.java | 27 +++ .../godepth/FindNodeFromEndLinklist/Node.java | 21 +++ .../godepth/LoopLinkedList/DetectLoop.java | 75 ++++++++ .../LoopLinkedList/LoopLinkedList.java | 52 ++++++ Java/src/com/godepth/LoopLinkedList/Node.java | 33 ++++ Java/src/com/godepth/Main.java | 65 ++++++- .../doublelinkedlist/DoubleLinkedList.java | 167 ++++++++++++++++++ .../com/godepth/doublelinkedlist/Node.java | 54 ++++++ .../singlelinkedlist/SingleLinkedList.java | 16 +- 10 files changed, 561 insertions(+), 3 deletions(-) create mode 100644 Java/src/com/godepth/FindNodeFromEndLinklist/FindNodeEfficient.java create mode 100644 Java/src/com/godepth/FindNodeFromEndLinklist/FindNodeHashTable.java create mode 100644 Java/src/com/godepth/FindNodeFromEndLinklist/Node.java create mode 100644 Java/src/com/godepth/LoopLinkedList/DetectLoop.java create mode 100644 Java/src/com/godepth/LoopLinkedList/LoopLinkedList.java create mode 100644 Java/src/com/godepth/LoopLinkedList/Node.java create mode 100644 Java/src/com/godepth/doublelinkedlist/DoubleLinkedList.java create mode 100644 Java/src/com/godepth/doublelinkedlist/Node.java diff --git a/Java/src/com/godepth/FindNodeFromEndLinklist/FindNodeEfficient.java b/Java/src/com/godepth/FindNodeFromEndLinklist/FindNodeEfficient.java new file mode 100644 index 0000000..a87037a --- /dev/null +++ b/Java/src/com/godepth/FindNodeFromEndLinklist/FindNodeEfficient.java @@ -0,0 +1,54 @@ +package com.godepth.FindNodeFromEndLinklist; + +import java.util.LinkedList; +import java.util.List; + +public class FindNodeEfficient { + + private LinkedList> linkList = null; + private Node nthNode = null; + private Node pTemp = null; + + public FindNodeEfficient(List arrayList) + { + this.linkList = new LinkedList<>(); + + for(T element : arrayList) { + Node node = new Node<>(); + node.setData(element); + this.linkList.add(node); + } + } + + public void find(int position) + { + int count = 0; + int tempCount = 0; + + for (Node i : this.linkList) { + System.out.println(i.getData()); + } + + this.pTemp = this.linkList.getFirst(); + + Node last = this.linkList.getLast(); + + while (this.pTemp != last) { + if (count < position - 1) { + this.pTemp = this.linkList.get(count); + } else { + this.nthNode = this.linkList.get(tempCount); + this.pTemp = this.linkList.get(count); + tempCount++; + } + count++; + } + + if (this.nthNode == null) { + System.out.println("Cannot find the " + position + "th node from the end of the link list!"); + } else { + System.out.println("The " + position + "th node data from the end of the link list is " + this.nthNode.getData()); + } + } + +} diff --git a/Java/src/com/godepth/FindNodeFromEndLinklist/FindNodeHashTable.java b/Java/src/com/godepth/FindNodeFromEndLinklist/FindNodeHashTable.java new file mode 100644 index 0000000..d838962 --- /dev/null +++ b/Java/src/com/godepth/FindNodeFromEndLinklist/FindNodeHashTable.java @@ -0,0 +1,27 @@ +package com.godepth.FindNodeFromEndLinklist; + +import java.util.LinkedList; +import java.util.List; + +public class FindNodeHashTable { + + private LinkedList> linkList = new LinkedList<>(); + + public FindNodeHashTable(List list) + { + for (T i : list) { + Node node = new Node<>(); + node.setData(i); + this.linkList.add(node); + } + } + + public void find(int position) { + + int size = this.linkList.size(); + + int target = size - position; + + System.out.println("The " + position + "th node from the end of the link list is '" + this.linkList.get(target).getData() + "'"); + } +} diff --git a/Java/src/com/godepth/FindNodeFromEndLinklist/Node.java b/Java/src/com/godepth/FindNodeFromEndLinklist/Node.java new file mode 100644 index 0000000..f693e20 --- /dev/null +++ b/Java/src/com/godepth/FindNodeFromEndLinklist/Node.java @@ -0,0 +1,21 @@ +package com.godepth.FindNodeFromEndLinklist; + +public class Node implements Comparable { + private T data; + + public T getData() + { + return this.data; + } + + public void setData(T data) + { + this.data = data; + } + + @Override + public int compareTo(T data) + { + return this.getData() == data ? 0 : 1; + } +} diff --git a/Java/src/com/godepth/LoopLinkedList/DetectLoop.java b/Java/src/com/godepth/LoopLinkedList/DetectLoop.java new file mode 100644 index 0000000..e705781 --- /dev/null +++ b/Java/src/com/godepth/LoopLinkedList/DetectLoop.java @@ -0,0 +1,75 @@ +package com.godepth.LoopLinkedList; + +import com.godepth.FindNodeFromEndLinklist.FindNodeHashTable; + +import java.util.List; + +public class DetectLoop { + + private LoopLinkedList loopLinkedList = null; + + private Node harePointer = null; + + private Node tortisePointer = null; + + public DetectLoop(List list, int loopFrom) + { + this.loopLinkedList = new LoopLinkedList<>(); + + for (T i : list) { + this.loopLinkedList.push(i); + } + + //Create the loop + this.loopLinkedList.makeLoop(2); + } + + public void find() + { + if (this.loopLinkedList != null) { + Node current = this.loopLinkedList.getHead(); + +// while (current != null) { +// System.out.println(current.getData()); +// current = current.getNext(); +// } + + this.tortisePointer = current; + this.harePointer = current.getNext(); + boolean flag = false; + + while (true) { + + if (this.harePointer == this.tortisePointer) { + flag = true; + break; + } else { + if (this.tortisePointer.getNext() != null) { + this.tortisePointer = this.tortisePointer.getNext(); + } else { + flag = false; + break; + } + + if (this.harePointer.getNext() != null && this.harePointer.getNext().getNext() != null) { + this.harePointer = this.harePointer.getNext().getNext(); + } else { + flag = false; + break; + } + } + } + + if (!flag) { + System.out.println("Loop not detected!"); + } else { + System.out.println("Loop detected!"); + } + + } else { + System.out.println("The link list is empty."); + } + + } + +} diff --git a/Java/src/com/godepth/LoopLinkedList/LoopLinkedList.java b/Java/src/com/godepth/LoopLinkedList/LoopLinkedList.java new file mode 100644 index 0000000..17dcd0f --- /dev/null +++ b/Java/src/com/godepth/LoopLinkedList/LoopLinkedList.java @@ -0,0 +1,52 @@ +package com.godepth.LoopLinkedList; + + +import java.util.List; + +public class LoopLinkedList { + + private Node head = null; + private Node tail = null; + private Node previous = null; + + public void push(T element) + { + Node newNode = new Node<>(); + newNode.setData(element); + + if (this.previous == null) { + this.head = newNode; + } else { + this.previous.setNext(newNode); + } + + this.previous = newNode; + + this.tail = newNode; + } + + public Node getHead() + { + return this.head; + } + + public Node getTail() + { + return this.tail; + } + + public void makeLoop(int position) + { + Node node = this.head.getNext(); + int count = 0; + + while (node != null) { + node = node.getNext(); + if (count == position) { + this.tail.setNext(node); + break; + } + count++; + } + } +} diff --git a/Java/src/com/godepth/LoopLinkedList/Node.java b/Java/src/com/godepth/LoopLinkedList/Node.java new file mode 100644 index 0000000..db57a66 --- /dev/null +++ b/Java/src/com/godepth/LoopLinkedList/Node.java @@ -0,0 +1,33 @@ +package com.godepth.LoopLinkedList; + +public class Node implements Comparable { + + private T data; + private Node next = null; + + public T getData() + { + return this.data; + } + + public void setData(T data) + { + this.data = data; + } + + public Node getNext() + { + return this.next; + } + + public void setNext(Node node) + { + this.next = node; + } + + @Override + public int compareTo(T data) + { + return this.getData() == data ? 0 : 1; + } +} diff --git a/Java/src/com/godepth/Main.java b/Java/src/com/godepth/Main.java index 85b2193..26d326a 100644 --- a/Java/src/com/godepth/Main.java +++ b/Java/src/com/godepth/Main.java @@ -1,10 +1,16 @@ package com.godepth; +import com.godepth.LoopLinkedList.DetectLoop; +import com.godepth.FindNodeFromEndLinklist.FindNodeEfficient; +import com.godepth.FindNodeFromEndLinklist.FindNodeHashTable; +import com.godepth.doublelinkedlist.DoubleLinkedList; import com.godepth.island.Island; import com.godepth.pathfinder.Pathfinder; import com.godepth.singlelinkedlist.SingleLinkedList; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public class Main { @@ -12,7 +18,11 @@ public static void main(String[] args) { //runIslandCounter(); //runPathFinder(); - runSingleLinkedList(); + //runSingleLinkedList(); + //runDoubleLinkedList(); + //runFindNodeFromEndEfficiently(); + //runFindNodeFromEndHashTable(); + runDetectLoopInLinkList(); } private static void runIslandCounter() @@ -43,7 +53,7 @@ private static void runPathFinder() private static void runSingleLinkedList() { - SingleLinkedList linkedList = new SingleLinkedList(); + SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(1); linkedList.add(2); @@ -60,4 +70,55 @@ private static void runSingleLinkedList() linkedList.traverse(); } + private static void runDoubleLinkedList() + { + DoubleLinkedList linkedList = new DoubleLinkedList<>(); + + linkedList.addAtStart("0.5"); + linkedList.addAfter("First", "0.5"); + linkedList.addAfter("Second" ,"First"); + linkedList.addAfter("Third" ,"Second"); + linkedList.addAfter("2.5" ,"Second"); + linkedList.addAfter("Fourth", "Third"); + linkedList.addAfter("4.5", "Fourth"); + linkedList.removeFirst(); +// linkedList.removeLast(); + linkedList.remove("2.5"); + + linkedList.traverse(); + } + + private static void runFindNodeFromEndEfficiently() + { + List list = new ArrayList<>(); + Collections.addAll(list, 1,2,3,4,5,6,7,8,9,10); + FindNodeEfficient linkList = new FindNodeEfficient<>(list); + + linkList.find(9); + } + + private static void runFindNodeFromEndHashTable() + { + List list = new ArrayList<>(); + Collections.addAll( + list, + "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth" + ); + FindNodeHashTable linkList = new FindNodeHashTable<>(list); + + linkList.find(9); + } + + private static void runDetectLoopInLinkList() + { + List list = new ArrayList<>(); + Collections.addAll( + list, + "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth" + ); + + DetectLoop detectLoop = new DetectLoop<>(list, 3); + + detectLoop.find(); + } } diff --git a/Java/src/com/godepth/doublelinkedlist/DoubleLinkedList.java b/Java/src/com/godepth/doublelinkedlist/DoubleLinkedList.java new file mode 100644 index 0000000..090cb2d --- /dev/null +++ b/Java/src/com/godepth/doublelinkedlist/DoubleLinkedList.java @@ -0,0 +1,167 @@ +package com.godepth.doublelinkedlist; + +public class DoubleLinkedList { + + private Node start = null; + private Node end = null; + + public boolean addAtStart(T element) + { + Node node = new Node<>(); + node.setData(element); + + if (this.start == null && this.end == null) { + this.start = node; + node.setPrevious(null); + node.setNext(null); + this.end = node; + return true; + } + + return false; +// Node current = this.start.getNext(); +// +// node.setNext(current); +// node.setPrevious(null); +// current.setPrevious(node); +// +// this.start = node; +// +// return true; + } + + public boolean addAtEnd(T element) + { + Node node = new Node<>(); + node.setData(element); + + if (this.end == null && this.start == null) { + node.setPrevious(null); + node.setNext(null); + this.end = node; + return true; + } + + Node current = this.start.getNext(); + + while (current.getNext() != null) { + current = current.getNext(); + } + + current.setNext(node); + node.setPrevious(current); + node.setNext(null); + + this.end = node; + + return true; + } + + public boolean addAfter(T element, T after) + { + Node node = new Node<>(); + Node ref = new Node<>(); + node.setData(element); + + if (this.start == null) { + this.start = node; + return true; + } + + Node current = this.start; + + while (true) { + if (current == null) { + break; + } + if (current.compareTo(after) == 0) { + ref = current; + break; + } + current = current.getNext(); + } + + Node next = ref.getNext(); + ref.setNext(node); + node.setNext(next); + + node.setPrevious(ref); + + if (next != null) { + next.setPrevious(node); + } + + return true; + } + + public boolean removeFirst() + { + if (this.start == null) { + //TODO, throw an exception as list is empty + return false; + } + + Node node = this.start.getNext(); + this.start = node; + + return true; + } + + public boolean removeLast() + { + if (this.end == null) { + return false; + } + + Node end = this.end; + System.out.println(end); + System.out.println(end.getData()); + + this.end = end.getPrevious(); + end = null; + return true; + } + + public boolean remove(T element) + { + if (this.start == null) { + //TODO, throw an exception there is no element in list + return false; + } + + Node current = this.start; + + while (current.compareTo(element) == 1) { + current = current.getNext(); + } + + if (current.getNext() == null && current.compareTo(element) == 1) { + //TODO, unable to find the node + return false; + } + + Node previous = current.getPrevious(); + Node next = current.getNext(); + previous.setNext(next); + next.setPrevious(previous); + current = null; + + return true; + } + + public void traverse() + { + if (this.start == null) { + return; + } + + Node current = this.start; + + do { + System.out.println("Data: " + current.getData()); + current = current.getNext(); + } while (current != null); + + return; + } +} diff --git a/Java/src/com/godepth/doublelinkedlist/Node.java b/Java/src/com/godepth/doublelinkedlist/Node.java new file mode 100644 index 0000000..bf1b1e9 --- /dev/null +++ b/Java/src/com/godepth/doublelinkedlist/Node.java @@ -0,0 +1,54 @@ +package com.godepth.doublelinkedlist; + +public class Node implements Comparable{ + + private T data = null; + private Node next = null; + private Node previous = null; + + public void setData(T data) + { + this.data = data; + } + + public T getData() + { + return this.data; + } + + public void setNext(Node next) + { + this.next = next; + } + + public Node getNext() + { + return this.next; + } + + public boolean hasNext() + { + return this.next != null; + } + + public void setPrevious(Node previous) + { + this.previous = previous; + } + + public Node getPrevious() + { + return this.previous; + } + + public boolean hasPrevious() + { + return this.previous != null; + } + + @Override + public int compareTo(T arg) + { + return (arg == this.data) ? 0 : 1; + } +} diff --git a/Java/src/com/godepth/singlelinkedlist/SingleLinkedList.java b/Java/src/com/godepth/singlelinkedlist/SingleLinkedList.java index ee02f31..1f2ac85 100644 --- a/Java/src/com/godepth/singlelinkedlist/SingleLinkedList.java +++ b/Java/src/com/godepth/singlelinkedlist/SingleLinkedList.java @@ -7,7 +7,7 @@ public class SingleLinkedList { public void add(T element) { - Node node = new Node(); + Node node = new Node<>(); node.setData(element); System.out.println("Adding: " + element); @@ -101,6 +101,20 @@ public void removeAfter(T after) } } + public void deleteNode(T node) + { + Node current = this.start; + Node previous = current; + + while (current.compareTo(node) == 1) { + previous = current; + current = current.getNext(); + } + + previous.setNext(current); + + } + public void traverse() { Node current = this.start;