Merge Sort with Strings - java

I have a linked list in a class named WordNode, which holds the following attributes:
String _word; WordNode _next;
I have another class which is the "actual list" which only holds a reference to the head of the list, the class is called TextList and it receives a String and supposed to put every word of the String SORTED IN THE LIST. For example, for the sentence:
coding in Java is cool.
The linked list would look like:
coding >>> cool >>> Java >>> in >>> is.
The arrows are like pointers to the next node in the list.
I want to first take all the words and put them in a linked list (TextList class) and then make a MERGE SORT to sort the words in the linked list.
What I though of doing is taking a split method to split the list into two lists: "odd" and "evens", which is these methods:
private TextList splitOdds(){
boolean flag=true;
TextList odds=new TextList();
WordNode o=null;
WordNode ptr=_head;
while (ptr.getNext()!=null){
if(flag)
o=new WordNode(ptr.getWord(),o);
ptr=ptr.getNext();
flag=!flag;
}
odds._head=o;;
return odds;
}
private TextList splitEvens(){
boolean flag=true;
TextList evens=new TextList();
WordNode e=null;
WordNode ptr=this._head.getNext();
while (ptr!=null){
if(flag)
e=new WordNode(ptr.getWord(),e);
ptr=ptr.getNext();
flag=!flag;
}
evens._head=e;
return evens;
}
The split does work.
But I don't know where to continue from here. I want to call the split method, recursively and split the list until it is a list of one or two nodes, but I can't figure out how to do that.
Edit: can not use a third class, forhibited by the excercise. Also holding the length of TextList. Only holding number of times each word appears by an attribute on WordNode class.

This is of course assuming that you keep the length of the list at each insertion or deletion. All you have to do is split the list in half like this while keeping the head/root of the original list. You will not even need any intermediary list while implementing your merge sort.
LinkedList LinkedList::split(){
_Node_* p=head, *q=p;
for(int i=0; i<len/2; i++){
q=p;
p=p->next;
}
LinkedList ret;
ret.head=p;
ret.len=len-len/2;
len=len/2;
q->next=NULL;
return ret;
}

IMHO, the concept is wrong. You dont need to use merge-sort here. Try searching for PriorityQueue or actually BinaryHeap in order to solve this task. Secondly, merge sort on linked list is not a good idea since it will not be efficient at all. I think you should totally rework your solution.
NB. Just implement the operation YourLinkedList.getByIndex() for convinience, add the size atribute to hold the number of items in the linked list, then create one more linkedList and perform the bottom-up merge-sort like you would do with a simple array.
Structures:
public class Item {
private String word;
private Item next;
public Item(String word) {
this.word = word;
}
public Item getNext() {
return next;
}
public void setNext(Item next) {
this.next = next;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
}
Linked List:
public class LinkedList {
private int size = 0;
private Item first = null;
public void swapFragment(LinkedList list, int from, int to) {
if (from >= 0 && to < size) {
list.get(to-from).setNext(this.get(to+1));
if (from > 0) {
this.get(from-1).setNext(list.get(0));
} else {
this.first = list.get(0);
}
}
}
public void addItem(String word) {
if (first == null) {
first = new Item(word);
} else {
Item item = first;
while (item.getNext() != null) {
item = item.getNext();
}
item.setNext(new Item(word));
}
this.size++;
}
public Item get(int index) {
if (index >= size) {
return null;
} else {
Item item = first;
for(int i = 1; i <= index; i++) {
item = item.getNext();
}
return item;
}
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String toString() {
Item item = first;
String message = null;
if (item != null) {
message = item.getWord() + " ";
} else {
return null;
}
while (item.getNext() != null) {
item = item.getNext();
message = message + item.getWord() + " ";
}
return message;
}
}
Merge Sort:
public class ListMergeSort {
public void sort(LinkedList list, int lo, int hi) {
if (hi <= lo) {
return;
}
int mid = lo + (hi-lo)/2;
sort(list, lo, mid);
sort(list, mid+1, hi);
merge(list, lo, hi, mid);
}
private void merge(LinkedList list, int lo, int hi, int mid) {
int i = lo;
int j = mid+1;
LinkedList newList = new LinkedList();
for (int k = lo; k <= hi; k++) {
if (i > mid) {
newList.addItem(list.get(j).getWord());
j++;
} else if (j > hi) {
newList.addItem(list.get(i).getWord());
i++;
} else if (list.get(i).getWord().compareTo(list.get(j).getWord()) < 0) {
newList.addItem(list.get(i).getWord());
i++;
} else {
newList.addItem(list.get(j).getWord());
j++;
}
}
list.swapFragment(newList, lo, hi);
}
}
Test Class for Strings:
import org.junit.*;
public class MergeTest {
#Test
public void testWords() {
LinkedList list = new LinkedList();
list.addItem("word");
list.addItem("pipe");
list.addItem("trainer");
list.addItem("stark");
list.addItem("33");
list.addItem("dmitry");
ListMergeSort lms = new ListMergeSort();
lms.sort(list, 0, list.getSize()-1);
}
}
Now you just need to create a class which receives a string as an argument, splits it with String.split() and adds the resulting words into the internal LinkedList datastructure. Then you sort them inside with the merge sort and you get the result.

Related

How to speed up Depth First Search method?

I'm trying to do a Depth First Search of my graph, and something is slowing it down quite a lot and I'm not sure what.
Here is my Bag code:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Bag<Item> implements Iterable<Item> {
private Node<Item> first; // beginning of bag
private Node<Item> end;
private int n; // number of elements in bag
public int label;
public int edges;
public static class Node<Item> {
private Item item;
private Node<Item> next;
public int label;
public int edges;
}
public Bag() {
first = null; // empty bag initialized
end = null;
n = 0;
}
public void add(Item item) {
if (n==0) {
Node<Item> head = new Node<Item>(); // if bag is empty
first = head;
end = head;
head.item = item; // new node both first and end of bag
edges++;
n++;
}
else {
Node<Item> oldlast = end; // old last assigned to end of node
Node<Item> last = new Node<Item>();
last.item = item;
oldlast.next = last; // new node added after old last
end = last;
n++; // size increased
edges++;
}
}
public Iterator<Item> iterator() {
return new LinkedIterator(first); // returns an iterator that iterates over the items in this bag in arbitrary order
}
public class LinkedIterator implements Iterator<Item> {
private Node<Item> current;
public LinkedIterator(Node<Item> first) {
current = first; // iterator starts at head of bag
}
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException(); // if there is next item, current is moved to next
Item item = current.item;
current = current.next;
return item; // item is returned
}
}
}
Here is my driver:
import java.util.ArrayList;
import java.util.Random;
public class Driver {
public static ArrayList<Integer> randomNum(int howMany) {
ArrayList<Integer> numbers = new ArrayList<Integer>(howMany);
Random randomGenerator = new Random();
while (numbers.size() < howMany) {
int rand_int = randomGenerator.nextInt(10000);
if (!numbers.contains(rand_int)) {
numbers.add(rand_int);
}
}
return numbers;
}
public static void main(String[] args) {
ArrayList<Integer> num = randomNum(100);
Graph G = new Graph(num);
System.out.println("The length of longest path for this sequence with graph is: " + G.dfsStart(num));
}
}
I send an ArrayList of random integers to my dfsStart method from the driver, which looks at all the different paths for each starting node in my graph. my DepthFirstSearch method calls the getAdjList for each starting node to find its neighbors using my Bag adj, and then works its way down each path before backtracking.
Here is my Graph code, containing my longest path method:
import java.util.ArrayList;
import java.util.NoSuchElementException;
public class Graph {
public final int V; // initializing variables and data structures
public Bag<Integer>[] adj;
public int longestPath;
public Graph(ArrayList<Integer> numbers) {
try {
longestPath = 0;
this.V = numbers.size();
adj = (Bag<Integer>[]) new Bag[V]; // bag initialized
for (int v = 0; v < V; v++) {
adj[v] = new Bag<Integer>();
}
for (int i = 0; i < V; i++) {
adj[i].label = numbers.get(i);
int j = (i + 1);
while (j < numbers.size()) {
if (numbers.get(i) < numbers.get(j)) {
addEdge(i, numbers.get(j));
}
j++;
}
}
}
catch (NoSuchElementException e) {
throw new IllegalArgumentException("invalid input format in Graph constructor", e);
}
}
public void addEdge(int index, int num) {
adj[index].add(num);
}
public int getIndex(int num) {
for (int i = 0; i < adj.length; i++) {
if (adj[i].label == num) {
return i;
}
}
return -1;
}
public Bag<Integer> getAdjList(int source) {
Bag<Integer> adjList = null;
for (Bag<Integer> list : adj) {
if (list.label == source) {
adjList = list;
break;
}
}
return adjList;
}
public int dfsStart(ArrayList<Integer> numbers) {
for (int i=0;i<numbers.size();i++) {
// Print all paths from current node
depthFirstSearch(numbers.get(i),new ArrayList<>(300));
}
return longestPath;
}
public void depthFirstSearch(int src, ArrayList<Integer> current) {
current.add(src);
Bag<Integer> srcAdj = getAdjList(src);
if (srcAdj.size() == 0) {
// Leaf node
// Print this path
longestPath = Math.max(longestPath, current.size());
}
for (int links : srcAdj) {
depthFirstSearch(links, current);
}
current.remove(current.size()-1);
}
}
I believe the suggestion below helped get rid of the error, but it is still unbelievably slow when trying to find the longest path in a graph of more than 150 vertices.
Even for a small dense graph there can be many unique paths from a src node. I tested for this input [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25] there are 16777216 unique paths from all nodes. So you can expect OOM for bigger inputs. one way is to update the longestPath as soon as a path is found instead of adding it to the list.
Change this to later.
addtoCount(current.size());
to
longestPath = Math.max(longestPath, current.size());
Make sure longestPath is global and initialized to 0 before every test case.
Well, I do not know JAVA but that is an incredible lot of code for doing a simple thing such as depth first search.
In C++ it is done like this:
void cPathFinder::depthFirst(
int v)
{
// initialize visited flag for each node in graph
myPath.clear();
myPath.resize(nodeCount(), 0);
// start recursive search from starting node
depthRecurse(v, visitor);
}
void cPathFinder::depthRecurse(
int v )
{
// remember this node has been visited
myPath[v] = 1;
// look for new adjacent nodes
for (int w : adjacent(v))
if (!myPath[w])
{
// search from new node
depthRecurse(w);
}
}

Searching and deleting values in a circular linked list

I am trying to make an application that will loop through a circular linked list. As it does so, it will use another linked list of index values, and it will use these values to delete from the circular linked list.
I have it set up now where it should fetch the index value to be deleted from my random linked list via runRandomList() method. It then uses the rotate() method to loop through the circular linked list and deletes the value from it. It will then add the deleted value to "deletedLinked list". Then, control should return back to runRandomList() method and it should feed the rotate() method the next value from the random linked list. The circular linked list should begin traversing where it left off. It should keep track of the count and node it is on. The count should reset to 0 when it reaches the first node, so it can properly keep track of which index it is on.
Unfortunately, this is not happening. I have been trying different things for the last few days as the code stands right now; it enters into a continuous loop. the issue appears to be in the rotate method.
This is the rotate method code. My thought was the counter would advance until it matches the index input. If it reaches the first node, the counter would reset to 0 and then start to increment again until it reaches the index value.
private void rotate(int x)
{
while(counter <= x)
{
if(p == names.first)
{
counter = 0;
}
p = p.next;
counter++;
}
deleteList.add((String) p.value);
names.remove(x);
}
This is my linked list class:
public class List<T>{
/*
helper class, creates nodes
*/
public class Node {
T value;
Node next;
/*
Inner class constructors
*/
public Node(T value, Node next)
{
this.value = value;
this.next = next;
}
private Node(T value)
{
this.value = value;
}
}
/*
Outer class constructor
*/
Node first;
Node last;
public int size()
{
return size(first);
}
private int size(Node list)
{
if(list == null)
return 0;
else if(list == last)
return 1;
else
{
int size = size(list.next) + 1;
return size;
}
}
public void add(T value)
{
first = add(value, first);
}
private Node add(T value, Node list)
{
if(list == null)
{
last = new Node(value);
return last;
}
else
list.next = add(value, list.next);
return list;
}
public void setCircularList()
{
last.next = first;
}
public void show()
{
Node e = first;
while (e != null)
{
System.out.println(e.value);
e = e.next;
}
}
#Override
public String toString()
{
StringBuilder strBuilder = new StringBuilder();
// Use p to walk down the linked list
Node p = first;
while (p != null)
{
strBuilder.append(p.value + "\n");
p = p.next;
}
return strBuilder.toString();
}
public boolean isEmpty()
{
boolean result = isEmpty(first);
return result;
}
private boolean isEmpty(Node first)
{
return first == null;
}
public class RemovalResult
{
Node node; // The node removed from the list
Node list; // The list remaining after the removal
RemovalResult(Node remNode, Node remList)
{
node = remNode;
list = remList;
}
}
/**
The remove method removes the element at an index.
#param index The index of the element to remove.
#return The element removed.
#exception IndexOutOfBoundsException When index is
out of bounds.
*/
public T remove(int index)
{
// Pass the job on to the recursive version
RemovalResult remRes = remove(index, first);
T element = remRes.node.value; // Element to return
first = remRes.list; // Remaining list
return element;
}
/**
The private remove method recursively removes
the node at the given index from a list.
#param index The position of the node to remove.
#param list The list from which to remove a node.
#return The result of removing the node from the list.
#exception IndexOutOfBoundsException When index is
out of bounds.
*/
private RemovalResult remove(int index, Node list)
{
if (index < 0 || index >= size())
{
String message = String.valueOf(index);
throw new IndexOutOfBoundsException(message);
}
if (index == 0)
{
// Remove the first node on list
RemovalResult remRes;
remRes = new RemovalResult(list, list.next);
list.next = null;
return remRes;
}
// Recursively remove the element at index-1 in the tail
RemovalResult remRes;
remRes = remove(index-1, list.next);
// Replace the tail with the results and return
// after modifying the list part of RemovalResult
list.next = remRes.list;
remRes.list = list;
return remRes;
}
}
This contains the main(), runRandomList(), and rotate() methods.
public class lottery {
private int suitors;
private List<String> names;
private List<Integer> random;
private List<String> deleteList = new List<>();
private int counter;
private Node p;
public lottery(int suitors, List<String> names, List<Integer> random)
{
this.suitors = suitors;
this.names = names;
this.random = random;
p = names.first;
}
public void start()
{
//Set names list to circular
names.setCircularList();
runRandomList(random);
}
public void runRandomList(List<Integer> random)
{
Node i = random.first;
while(i != null)
{
rotate((int) i.value, counter, p);
i = i.next;
}
}
public List getDeleteList()
{
return deleteList;
}
private void rotate(int x, int count, Node p)
{
Node i = p;
while(count <= x)
{
if(i == names.first)
{
count = 0;
}
i = i.next;
count++;
}
deleteList.add((String) i.value);
names.remove(x);
p = i;
counter = count;
}
public static void main(String[] args)
{
List<String> namesList = new List<>();
namesList.add("a");
namesList.add("b");
namesList.add("c");
namesList.add("d");
namesList.add("e");
namesList.add("f");
List<Integer> randomList = new List<>();
randomList.add(3);
randomList.add(1);
randomList.add(5);
randomList.add(4);
randomList.add(0);
lottery obj = new lottery(6, namesList, randomList);
obj.start();
System.out.println(obj.getDeleteList());
}
}
As I suspected it was the rotate method, this is the solution.
private void rotate(int x, int count)
{
while(count != x)
{
p = p.next;
count++;
if(count == x)
{
deleteList.add((String)p.value);
counter = x;
}
if(count >= suitors)
{
for (int j = 0; j < x ; j++)
{
p = p.next;
}
deleteList.add((String)p.value);
counter = x;
count = x;
}
}
}

Linked list printing blank

My linked list is printing blank. Can someone explain what I am missing here.
class Linklist {
private Linklist first;
public int items;
public int itemLocation;
public int lastIndex = -1;
private final String[] list;
public Linklist nextlink;
//Link constructor
public Linklist(int totalItems) {
items = 0;
list = new String[totalItems];
}
public Linklist getNext()
{
return this.nextlink;
}
public void setNext(Linklist n)
{
nextlink = n;
}
public void insert (String item){
list[items] = item;
items++;
}
public void delete(String item){
int location = 0;
while(item.compareTo(list[location]) != 0)
location++;
list[location] = list[items -1];
items--;
}
public boolean doesExist (String item){
boolean search;
int location = 0;
boolean found = false;
search = (location < items);
while (search && !found)
{
if (item.compareTo(list[location])==0)
found = true;
else
{
location++;
search = (location<items);
}
}
return found;
}
public void printUnsortedlist(){
System.out.print("{" + list + "} ");
}
public void printList(){
Linklist currentLink = first;
System.out.print("List: ");
while(currentLink != null){
currentLink.printUnsortedlist();
currentLink = currentLink.getNext();
}
System.out.println("");
}
}
public class Unsortedlist{
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Linklist list = new Linklist(9);
list.insert("Sun");
list.insert("Mercury");
list.insert("Venus");
list.insert("Earth");
list.insert("Mars");
list.insert("Jupiter");
list.insert("Neptune");
list.insert("Saturn");
list.insert("Uranus");
list.printList();
list.delete("Sun");
if(list.doesExist("Earth"))
System.out.println("Earth is in the list");
else
System.out.println("Earth does not exist!");
list.printList();
}
}
This is my output:
List:
Earth is in the list
List:
BUILD SUCCESSFUL (total time: 0 seconds)
When I integrate a size() method for example:
public int size(){
int currentSize = 0;
Linklist current = head;
while(current != null){
currentSize = currentSize + 1;
current = current.getNext();
}
return currentSize;
}
I get this as the output:
{8} Earth is in the list
My linked list is there but can not figure out why it is printing blank.
For your code ,a few places make me more confused.
First,Why you already have a field "list" ,but then you also set a pointer to the nextlink,if you just want to print as a list ,you could only set two field String value and Linklist next,then you can print your list .
Second,I think the reason why your list is blank is that you set first to currentLink ,and first is null all the time.To solve this problem ,maybe you can change first to this,then your while code will run as you like it.
Just like this:
public void printList(){
Linklist currentLink = this;
System.out.print("List: ");
while(currentLink != null){
currentLink.printUnsortedlist();
currentLink = currentLink.getNext();
}
System.out.println("");
}
But still ,you need to improve your code at many places is you really want the code do a perfect job.Hope this help you out.

How can I remove a randomly chosen element from a linked list?

I am trying to do an assignment for a class where I use the remove method of a String Bag class to return all the elements of a linked list, one at a time, then delete that element from the list. I have a start, but I can't figure out exactly how to do it. Can anyone help?
public String remove()
{
Random rand = new Random();
int randNum = rand.nextInt(numItems);
//generate random number
int count = 0;
String get;
currNode = firstNode;
//temporary node to get String from
while(count < randNum)
{
currNode = currNode.getLink();
count++;
}
//randomly select node to get String from
get = currNode.getInfo();
numItems--;
if(numItems == 0)
{
firstNode = null;
}
//decrement the number of items in the bag and make the first node
//null when it reaches 0
return get;
}
edit: Here is the application level:
public class StringBagTest
{
public static void main(String[] args)
{
LLStringBag bag = new LLStringBag();
bag.insert("Hat");
bag.insert("Shirt");
bag.insert("Pants");
bag.insert("Shoes");
//insert 4 strings into the list
while(!bag.isEmpty())
{
System.out.println(bag.remove());
}
//randomly removes all contents of list
}
}
If you want to remove randomly chosen element by index then it looks something like this:
public void removeRandomElement() {
int index = new Random().nextInt(size);
Node current = head;
Node prev = head;
for (int i = 0; i < index; i++) {
prev = current;
current = current.next;
}
prev.next = current.next;
current.next = null;
size--;
}
For singly linked list, where size is current size of the list, head — head node.
In other terms, you're doing something like this on the selected element :
Take a look at this link:
link
Also a full example:(making your own Links and Lists)
(The example below is a Linked list which have(links) it's link is a point for example A(50,3). You can transform it to be whatever you want...)
The Link
public class DoublePoint {
public double X;
public double Y;
public int LinkKey=0;
public DoublePoint nextLink; //keeps the nextLink
//Constructor
public DoublePoint(double Xpos,double Ypos,int key){
X=Xpos;
Y=Ypos;
LinkKey=key;
}
public void printLinkKey(){
System.out.println(LinkKey);
}
//Return Link key
public String returnLinkKey(){
return ""+LinkKey;
}
public void changeContent(double x,double y){
X=x;
Y=y;
}
public void ChangeLinkKey(int key){
LinkKey=key;
}
}
The List:
public class ListDoublePoints {
public DoublePoint first;
public int key;
public int totalLinks=0;
public ListDoublePoints(){
first=null;
key=0;
}
//Insert
public void insertLink(double x,double y){
DoublePoint newLink = new DoublePoint(x,y,key);
newLink.nextLink=first;
first=newLink;
key++;
totalLinks++;
}
//Find
public DoublePoint findLinkAt(int key){
DoublePoint current=first;
while(current.LinkKey!=key){
if(current.nextLink==null)
return null;
else
current=current.nextLink;
}
return current;
}
//Delete using Link key (similar with remove(int position) with ready java lists)
public String deleteLinkAt(int linkKey){
DoublePoint current =first;
DoublePoint previous=first;
while(current.LinkKey !=linkKey){
if(current.nextLink == null ){
return "boom";}
else
previous=current;
current=current.nextLink;
}
if(current==first)
first=first.nextLink;
else
previous.nextLink=current.nextLink;
--totalLinks;
return "ok";
}
//Return
public int LinksNumber(){
return totalLinks;
}
//Print
public void displayList(){
DoublePoint current=first;
while(current!=null){
current.displayLink();
current=current.nextLink;
}
}
public void displayTheNumberOfLinks(){
System.out.println(totalLinks);
}
}
*Let me know if you want something like this above or
just to work with the java ready lists..*
If you want to remove all elements of a linked list, you can use the built in clear() method.
If you don't want to use that method, you can just set the head node to null. The garbage collector will take care of the rest.
If you want a remove method that removes one thing at a time and you don't care what it removes, I suggest just removing the first element you find. If it's in a linked list, you can just assign a temp node to the head node, reassign the head node to the next node, and return the temp node.
Do you mean something like this???
Code
private LinkedList<String> list = new LinkedList<>();
private void fillList() {
for (int i = 0; i < 10; i++) {
list.add("Hello " + i);
}
}
private void removeAllRandomly() {
Random random = new Random();
while (!list.isEmpty()) {
int randomPosition = random.nextInt(list.size());
String s = list.remove(randomPosition);
System.out.println(String.format("Item on position: %s (%s) was removed", randomPosition, s));
}
}
Result
Item on position: 9 (Hello 9) was removed
Item on position: 1 (Hello 1) was removed
Item on position: 1 (Hello 2) was removed
Item on position: 2 (Hello 4) was removed
Item on position: 5 (Hello 8) was removed
Item on position: 0 (Hello 0) was removed
Item on position: 3 (Hello 7) was removed
Item on position: 1 (Hello 5) was removed
Item on position: 1 (Hello 6) was removed
Item on position: 0 (Hello 3) was removed

How to remove the maximum value from a PQ (singly-linked list)

I'm trying to implement a removeMax() method in this PQ class. The PQ is implemented with a singly-linked list. I can't seem to wrap my head around how you could scan the entire list for the largest value. Any guidance would be appreciated. Here's the whole class:
import java.util.NoSuchElementException;
public class UnorderedLinkedListMaxPQ<Item extends Comparable<Item>> {
private int N;
private Node first;
private class Node {
private Item item;
private Node next;
}
public UnorderedLinkedListMaxPQ() {
first = null;
N = 0;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
public void insert(Item item) {
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
}
public Item removeMax() {
if (isEmpty()) { throw new NoSuchElementException("PQ underflow"); }
else if (N == 1) {
Item item = first.item;
first = first.next;
N--;
return item;
}
else if (N != 0) {
// ?
}
}
public String toString() {
Node counter = first;
String string = "";
while (counter != null) {
string = string + counter.item + ", ";
counter = counter.next;
}
return string;
}
private boolean less(Item v, Item w) {
return (v.compareTo(w) < 0);
}
public static void main(String[] args) {
UnorderedLinkedListMaxPQ<Integer> pq = new UnorderedLinkedListMaxPQ<Integer>();
pq.insert(32);
pq.insert(7);
pq.insert(18);
pq.insert(2);
StdOut.println("The priority queue contains (" + pq.toString() + "). \n");
while (!pq.isEmpty())
StdOut.println(pq.removeMax());
}
}
Generally when iterating through a linked list manually, you make a variable called walker and initialize it to first. Then you can do something like this
while (walker != null) {
// Do something
walker = walker.next;
}
to traverse through the list. In your case, you'll need to keep track of the maximum value as you traverse.
To remove a value from a linked list, you "link around it", meaning that you set the previous node's next to the next of the value you're trying to remove. Since your list is singly-linked, you also need to keep track of the previous element as you go along, because otherwise you have a pointer to it after you decide which element you're removing.
Example:
aNode.next = aNode.next.next;
This removes the node aNode.next from your linked-list.
java hasPriorityQueue , you dont have to impl yourself
see doc here
http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
PQ is impl by HEAP
http://en.wikipedia.org/wiki/Heap_(data_structure)
remove is O(lgn) no need to scan through
You know how to scan the list you do that in toString
The items extend comparable so you can compare them to each other.
Start with a max set to the first and iterate through compaing to max, if the value's greater set max to it.
Because you're doing a remove and the list is a single link one you'll need to remember the previous node to max too you'll need to set it's next to that of max afterwards.
Another approach is to scan down the list on insert and insert in order the the max is then always the first.

Categories

Resources