Implementing Java Priority Queue - java

public class PriorityQueue<T> {
private PriorityNode<T> head, tail;
private int numItems;
public PriorityQueue(){
numItems = 0;
head=null;
tail=null;
}
public void add(int priority, T value){
PriorityNode<T> newNode = new PriorityNode<T>(priority,value);
if(numItems == 0){
head = newNode;
tail = newNode;
}
else{
head.setNext(newNode);
head = newNode;
}
}
}
Where PriorityNode is defined as:
public class PriorityNode<T> implements Comparable<T> {
private T value;
private PriorityNode<T> next;
private int priority;
public PriorityNode(int priority,T newValue){
value = newValue;
next = null;
priority = 0;
}
public PriorityNode(T newValue){
value = newValue;
next = null;
priority = 0;
}
public void setPriority(int priority){
this.priority = priority;
}
public int getPriority(){
return this.priority;
}
public T getValue(){
return value;
}
public PriorityNode<T> getNext(){
return next;
}
public void setNext(PriorityNode<T> nextNode){
this.next = nextNode;
}
public void setValue(T newValue){
value = newValue;
}
#Override
public int compareTo(int pri) {
// TODO Auto-generated method stub
if(this.priority<pri){
return -1;
}
else if(this.priority == pri){
return 0;
}
else{
return 1;
}
}
}
I'm having a lot of difficulty using the Comparator here and implementing a priority queue - please point me in the right direction.

Don't use a tree structure to implement a priority queue. Use a heap. It is more space-efficient, requires fewer memory allocations, and is O(log(N)) for most operations.

Regarding the implementing of the comparator, implementing the Comparator<T> or Comparable<T> interface requires the public int compareTo(T o) method to be overridden.
In the example code given, the compareTo(T) method is not overridden (the compareTo(int) method is defined, but that is not the same method signature), therefore, it will probably lead to a compiler error.

I think you are making it a bit too tough on yourself, a priority queue is efficiently implemented with array-based heaps: simpler and more efficient (read: contiguous memory areas).

Related

Java Iterable<Node> inheritance

Before all, here is a Minimal Working Example of my code on GitHub:
https://github.com/rmwesley/DancingLinks_MWE
I've been trying to implement the Dancing Links' algorithm by D. Knuth to solve the Exact Cover problem.
The code works. Problem is, I want to implement an Iterator.
In fact, the Iterator works for Node.java.
But not for Column.java, as I will further detail.
I've tried completely refactoring the code and doing some crazy modifications, but to no avail.
I left some of my best trials as commented lines of code.
These were the least garbagey ones.
My current design is as follows:
Given a problem matrix, I aimed at constructing the main data structure with 4-way nodes.
So first I implemented Node.java, a 4-way circularly linked data structure.
Then I extend Node.java in Column.java, which is the "backbone" of the structure.
Column elements then make up the main row.
Rows of Nodes are then linked with the rest of the structure with .addRow().
That is, new rows come below the last added row and above the column. Remember, circular.
See the schematics in D. Knuth's paper: https://arxiv.org/abs/cs/0011047.
With this, the full structure can be initialized from a given problem matrix.
"this" in Column serves as the head itself, so no elements are added above or below it.
Here is my source code:
Node.java
public class Node implements Iterable<Node> {
private Node upNode;
private Node downNode;
private Node leftNode;
private Node rightNode;
private Column column;
public Node() {
upNode = this;
downNode = this;
leftNode = this;
rightNode = this;
column = null;
}
#Override
public String toString() {
String str = this.column.getSize() + " ";
for (Node node : this){
str += node.column.getSize() + " ";
}
return str;
}
#Override
public java.util.Iterator<Node> iterator(){
Node currNode = this;
return new NodeIter(this);
}
public Column getColumn(){
return this.column;
}
public void setColumn(Column column){
this.column = column;
}
public Node getR(){
return this.rightNode;
}
public Node getD(){
return this.downNode;
}
public Node getL(){
return this.leftNode;
}
public Node getU(){
return this.upNode;
}
void removeHoriz() {
this.rightNode.leftNode = this.leftNode;
this.leftNode.rightNode = this.rightNode;
}
void removeVert() {
this.downNode.upNode = this.upNode;
this.upNode.downNode = this.downNode;
}
void restoreVert() {
this.downNode.upNode = this;
this.upNode.downNode = this;
}
void restoreHoriz() {
this.rightNode.leftNode = this;
this.leftNode.rightNode = this;
}
//Create an horizontal link between nodes
public void linkD(Node other) {
this.downNode = other;
other.upNode = this;
}
//Create a vertical link between nodes
public void linkR(Node other) {
this.rightNode = other;
other.leftNode = this;
}
void addHoriz(Node other) {
other.rightNode = this.rightNode;
other.leftNode = this;
}
void addVert(Node other) {
other.downNode = this.downNode;
other.upNode = this;
}
}
Column.java
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
//public class Column extends Node implements Iterable<Column>{
public class Column extends Node {
private int size;
private String name;
public Column() {
super();
this.setColumn(this);
size = 0;
name = new String();
}
public Column(int length) {
this();
Column currColumn = this;
for(int i = 0; i < length; i++){
currColumn.setName("" + i);
Column nextColumn = new Column();
currColumn.linkR(nextColumn);
currColumn = nextColumn;
}
currColumn.linkR(this);
}
public void addRow(int[] vector) throws Exception {
Column currColumn = this;
Node firstNode = new Node();
Node currNode = firstNode;
Node prevNode = currNode;
for(int index=0; index < vector.length; index++){
currColumn = currColumn.getR();
if(vector[index] == 0) continue;
currColumn.increment();
currColumn.getU().linkD(currNode);
currNode.linkD(currColumn);
currNode.setColumn(currColumn);
prevNode = currNode;
currNode = new Node();
prevNode.linkR(currNode);
}
currColumn = currColumn.getR();
prevNode.linkR(firstNode);
if(currColumn != this){
throw new Exception("Differ in length");
}
}
public Column(int[][] matrix) throws Exception {
this(matrix[0].length);
for(int i = 0; i < matrix.length; i++){
this.addRow(matrix[i]);
}
}
#Override
public Column getR(){
return (Column) super.getR();
}
#Override
public Column getL(){
return (Column) super.getL();
}
#Override
public String toString(){
String str = "";
//for (Column currColumn : this) str += currColumn.getSize() + " ";
for (Column currColumn = this.getR();
currColumn != this;
currColumn = currColumn.getR()){
str += currColumn.getSize() + " ";
}
return str;
}
public String getName(){
return this.name;
}
public int getSize(){
return this.size;
}
public void setSize(int size){
this.size = size;
}
public void setName(String name){
this.name = name;
}
public void increment(){
this.size++;
}
public void decrement(){
this.size--;
}
/*
#Override
public Iterator<Column> iterator(){
return new Iterator<Column>(){
private Column currNode = Column.this;
#Override
public boolean hasNext(){
return currNode.getR() != Column.this;
}
#Override
public Column next(){
if (!hasNext()) throw new NoSuchElementException();
currNode = currNode.getR();
return currNode;
}
};
}
*/
}
NodeIter.java
public class NodeIter implements java.util.Iterator<Node>{
private Node head;
private Node current;
public NodeIter(Node node){
this.head = this.current = node;
}
#Override
public boolean hasNext(){
return current.getR() != head;
}
#Override
public Node next(){
if (!hasNext()) throw new java.util.NoSuchElementException();
current = current.getR();
return current;
}
}
Commented lines give these errors when uncommented:
src/Column.java:5: error: Iterable cannot be inherited with different arguments: <Column> and <Node>
public class Column extends Node implements Iterable<Column>{
^
src/Column.java:111: error: iterator() in Column cannot implement iterator() in Iterable
public Iterator<Column> iterator(){
^
return type Iterator<Column> is not compatible with Iterator<Node>
where T is a type-variable:
T extends Object declared in interface Iterable
src/Column.java:76: error: incompatible types: Node cannot be converted to Column
for (Column currColumn : this) str += currColumn.getSize() + " ";
How do I make Column.java iterable?
I've been coding in Java recently, but without carefully considering design patterns.
So I fully believe I am suffering the consequences of bad code design.
Should I make some abstract class or make use of some Generic Type?
Like Node and Column, just so I can implement Iterable.
Am I wrong?
Does anyone have any pointers?
Tried using generics and overriding .iterator() method with different return types in Column.java.
Even tried using completely different class structures.
The Node class has an implementation of the Iterable interface in the form of one method:
#Override
public java.util.Iterator<Node> iterator(){
Node currNode = this;
return new NodeIter(this);
}
(BTW the first line of this method is not doing anything useful)
You are trying to make Node's subclass Column implement Iterable, meaning you want to add an overriding method like this:
#Override
public Iterator<Column> iterator()
Such an override which only differs in return type is not allowed in Java, hence the compilation error.
The fundamental problem is that, since Node is an Iterable, all its subclasses will also be an Iterable due to inheritance.
I guess you would like to write code like this:
for(Node n : node) {
for(Column c : n.getColumn()) {
c.increment();
}
}
Currently I think you could do this:
for(Node n : node) {
for(Node c : n.getColumn()) {
((Column) c).increment();
}
}
Where you are casting the iterand to Column in order to access Column methods.
I do think the design is weird when I read this for instance:
public Column() {
super();
this.setColumn(this);
eh? So a Column is a Node which has a column field? Seems like the design is conflicted about whether a Column is-a Node, or a Node has-a Column... I feel like your iterable problem will magically disappear once you figure that out.
EDIT: I don't fully grasp the algorithm and data structure yet (although I read a bit about it). From what I've understood I think you should create something like the following structure:
class Matrix {
Column[] columns;
Matrix(int[][] input) {
// init Columns
}
}
class Column {
String name;
int size;
Node firstNode;
}
class Node {
Node up;
Node down;
Node left;
Node right;
}
And avoid sub classing, it's usually not needed. Better to work with interfaces and collaborators.

How to determine Big-Oh for run time analysis?

I am trying to do runtime analysis for the class "SlowMaxStack"'s method IsEmpty(), Push(), Pop(), and getMaxSoFar().
Here is my guess, but I'm not sure about the answer is correct and I also doubt about my reasoning.
IsEmpty(): o(1), simply check the top node. constant
Push(): o(1), simply putting the data in the top node. constant
Pop(): o(1), guessing this might be o(3), but still constant so I think it's o(1)
getMaxSoFar(): o(n), since the for loop goes through the element till the length of the node element. From the top, 1 + n + 1 --> n + 2 - > o (n)
class ListNode<T>{
public T value;
public ListNode<T> next;
public ListNode(T value, ListNode<T> next)
{
this.value = value;
this.next = next;
}
public ListNode<T> setValue(T value)
{
return new ListNode<T>(value, this);
}
}
interface Maximizer<T> {
T getMax(T t1, T t2);
T getGlobalMin();
}
interface MaxStack<T>
{
boolean isEmpty();
void push(T value);
T pop();
T getMaxSoFar();
//returns the maximum value in the stack
}
class SlowMaxStack<T> implements MaxStack<T>
{
private final Maximizer<T> maximizer; //data
private ListNode<T> top; // node
public SlowMaxStack(Maximizer<T> maximizer)
{
this.maximizer = maximizer;
}
#Override
public boolean isEmpty()
{
return top == null;
}
#Override
public void push(T value)
{
if (top == null)
{
top = new ListNode<T>(value, null);
}
else
{
top = top.setValue(value);
}
}
#Override
public T pop()
{
T value = top.value;
top = top.next;
return value;
}
#Override
public T getMaxSoFar()
{
T currentMax = maximizer.getGlobalMin();
for(ListNode<T> node = top; node != null; node = node.next)
{
currentMax = maximizer.getMax(currentMax, node.value);
}
return currentMax;
}
}

Implementation of ArrayList using a LinkedList

I need to implement both a Queue and ArrayList by using an internal LinkedList. I created my DoublyLinkedList class and was able to implement it into my queue with no problem. The problem I am running into is that to add or delete to/from the ArrayList, the add/delete methods take in a integer for the index and an object/element. All my methods inside my DoublyLinkedList class take in either elements and/or Nodes.
My question is this, how can I implement my DoublyLinkedList methods inside my ArrayList when my DLL class doesn't take any int values in.
I want to be able to add or delete the node by using the index, but I can't. Realistically, I would want something like list.addAfter(I) without I being an integer.
Note: The goal of this assignment is to implement ADTs, so I can't modify the method signatures of the ArrayList ADT.
DoublyLinedList Class
public class DoublyLinkedList<E> {
private Node<E> head;
private Node<E> tail;
private int size;
public DoublyLinkedList() {
this.head = new Node<E>(null, null, null);
this.tail = new Node<E>(null, null, null);
this.size = 0;
head.setNext(tail);
tail.setPrev(head);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public Node<E> getPrev(Node<E> n) {
return n.getPrev();
}
public Node<E> getNext(Node<E> n) {
return n.getNext();
}
public Node<E> getFirst() {
return head.getNext();
}
public Node<E> getLast() {
return tail.getPrev();
}
public E remove(Node<E> c) {
Node<E> a = c.getPrev();
Node<E> b = c.getNext();
b.setNext(a);
a.setPrev(b);
c.setNext(null);
c.setPrev(null);
size--;
return c.getElement();
}
public E removeFirst() {
return remove(head.getNext()); // first element is beyond header
}
public E removeLast() {
return remove(tail.getPrev());
}
public void addBefore(Node<E> node, E e) {
Node<E> prev = getPrev(node);
Node<E> n = new Node<E>(e, prev, node);
node.setPrev(n);
prev.setNext(n);
size++;
}
public void addFirst(E e) {
addAfter(head, e);
}
public void addLast(E e) {
addBefore(tail, e);
}
public void addAfter(Node<E> node, E e) {
Node<E> next = getNext(node);
Node<E> n = new Node<E>(e, node, next);
node.setNext(n);
next.setPrev(n);
size++;
}
}
LArrayList class (my Arraylist implementation)
public class LArrayList implements List {
private DoublyLinkedList list;
private int size;
public LArrayList() {
this.list = new DoublyLinkedList();
this.size = 0;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void add(int I, Object e) throws IndexOutOfBoundsException {
if (isEmpty()) {
list.addFirst(e);
}
// HERE IS MY CONCERN. THESE FOUR METHODS ALL TAKE IN INT VALUES WHILE
// NON OF MY DLL METHODS DO!
}
public Object get(int i) throws IndexOutOfBoundsException {
return null;
}
public Object remove(int i) throws IndexOutOfBoundsException {
return null;
}
public Object set(int I, Object e) throws IndexOutOfBoundsException {
return null;
}
}
It seems like a fairly easy thing to do - just use the API exposed by your LinkedList and add some logic to it. Here is the bit you are missing
if (list.size() < I) {
throw new IndexOutOfBoundsException()
}
//get a starting point
Node node = list.getFirst();
//loop until you get to the specified position
while(I-- > 0) {
node = list.getNext(node);
}
//now node points at the node in position I - insert the new
//node before it to comply with the List interface
list.addBefore(node, e);
this.size++;
I do have to note that your LinkedList implementation can be improved - first of all, the getPrev() getNext() addBefore() and addAfter() should be static, as you shouldn't have to use a LinkedList instance to call them. However, it would be even better if the methods were actually methods in Node, because that way the traversal and usage of the LinkedList would be way more easy. Here is how the above code would look like if the methods were in Node:
if (list.size() < I) {
throw new IndexOutOfBoundsException()
}
//get a starting point
Node node = list.getFirst();
//loop until you get to the specified position
while(I-- > 0) {
node = node.getNext();
}
//now node points at the node in position I - insert the new
//node before it to comply with the List interface
node.addBefore(e);
this.size++;
You pretty much do not need the list at all - certainly you don't need to just pass extra parameters to some functions. You can still keep the (hopefully static) methods in Linked list that do the same thing, but they'd just be proxies for the Node implementation of the methods, e.g.:
public static void addAfter(Node<E> node, E e) {
node.addAfter(e);
}
I am not sure if you will need these methods in LinkedList but they can certainly be there for "backwards compliance", if you will.
EDIT Forgot to mention - the fist bit of code is the implementation for add(), I am sure you can work out the rest, as they'd do the same thing.
public Object get(int i) throws IndexOutOfBoundsException {
if(list.size()<=i) throw new IndexOutOfBoundsException();
Node current = list.getFirst();
for(int x = 0; x<=i; x++){
if(x == i) return current.getElement();//Change this behaviour for remove and set
current = current.getNext();
}
}

How would i compare two objects in custom tree set implementation?

I need to compare two objects in insert method off the tree set. But i am unable to fathom out where and how to implement Comparable or Comparator. My code looks as follows:
This is my Node creation for the binary tree.
Node.java
public class Node {
private Object data;
private Node left, right;
//initial case when a Node of a binary tree gets created. both left and right subtrees point to null
public Node (){
left = right = null;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
This is my MyBinaryTree class where i need to implement insert method:
MyBinaryTree.java
public class MyBinaryTree implements Comparable<Node> {
Node root;
public MyBinaryTree(){
root = null;
}
void insert(Object x){
Node newrec = new Node(); //Node constructor gets called and sets up a root node with empty
//subtrees
newrec.setData(x);
if(root == null){
root = newrec;
}
else{
Node a,b;
a = b = root;
while(a!=null){
b=a;
if( ( newrec.getData() ).compareTo( a.getData() ) ) {
i am stuck here! how would i compare these objects using Comparable?
}
}
}
}
void inorder(Node root){
}
#Override
public int compareTo(Node o) {
// TODO Auto-generated method stub
int i = (o.)
return 0;
}
}
You need to be able to compare, not just nodes, but the data contained in those nodes. That means that your Node either needs to be limited to taking objects that are Comparable, or your tree needs to take a Comparator that it can use to compare them.
If you really want to support both, then when the time comes to do the comparison, if a Comparator has been provided, use its compare method, otherwise cast the data to Comparable<? super E> where E is the type of Node data (see below), and then use its compareTo method.
That brings me to the next point. Your Node class should probably not simply contain Object as its data, but instead be declared as Node<E> implements Comparable<Node<E>>, and then your tree can be declared as MyBinaryTree<E>. I would also change the constructor for Node to take the data as a parameter, rather than calling the setter immediately after creating one. There is no reason you would ever want to create a Node with no data.
I would strongly suggest looking through the source code for some of the generic collections in the java.util package, which comes with the JDK. In particular, I referred to the source of TreeMap.java to see how they handled both Comparable and non-Comparable elements, since the class isn't declared in such a way as to require the elements to be Comparable. (If they aren't, and there is no Comparator, a ClassCastException would occur where they try to cast the object to Comparable<? super K>.) Seeing how they have implemented similar code will be a great help to you. You may also want to review Java generics.
Please refer below code
package com.example.treeset;
import java.util.Comparator;
import java.util.TreeSet;
public class MyCompUser {
public static void main(String a[]){
//By using name comparator (String comparison)
TreeSet<Empl> nameComp = new TreeSet<Empl>(new MyNameComp());
nameComp.add(new Empl("Ram",3000));
nameComp.add(new Empl("John",6000));
nameComp.add(new Empl("Crish",2000));
nameComp.add(new Empl("Tom",2400));
for(Empl e:nameComp){
System.out.println(e);
}
System.out.println("===========================");
//By using salary comparator (int comparison)
TreeSet<Empl> salComp = new TreeSet<Empl>(new MySalaryComp());
salComp.add(new Empl("Ram",3000));
salComp.add(new Empl("John",6000));
salComp.add(new Empl("Crish",2000));
salComp.add(new Empl("Tom",2400));
for(Empl e:salComp){
System.out.println(e);
}
}
}
class MyNameComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
return e1.getName().compareTo(e2.getName());
}
}
class MySalaryComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
if(e1.getSalary() > e2.getSalary()){
return 1;
} else {
return -1;
}
}
}
class Empl{
private String name;
private int salary;
public Empl(String n, int s){
this.name = n;
this.salary = s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public String toString(){
return "Name: "+this.name+"-- Salary: "+this.salary;
}
}

Doubly linked lists

I have an assignment that I am terribly lost on involving doubly linked lists (note, we are supposed to create it from scratch, not using built-in API's). The program is supposed to keep track of credit cards basically. My professor wants us to use doubly-linked lists to accomplish this. The problem is, the book does not go into detail on the subject (doesn't even show pseudo code involving doubly linked lists), it merely describes what a doubly linked list is and then talks with pictures and no code in a small paragraph. But anyway, I'm done complaining. I understand perfectly well how to create a node class and how it works. The problem is how do I use the nodes to create the list? Here is what I have so far.
public class CardInfo
{
private String name;
private String cardVendor;
private String dateOpened;
private double lastBalance;
private int accountStatus;
private final int MAX_NAME_LENGTH = 25;
private final int MAX_VENDOR_LENGTH = 15;
CardInfo()
{
}
CardInfo(String n, String v, String d, double b, int s)
{
setName(n);
setCardVendor(v);
setDateOpened(d);
setLastBalance(b);
setAccountStatus(s);
}
public String getName()
{
return name;
}
public String getCardVendor()
{
return cardVendor;
}
public String getDateOpened()
{
return dateOpened;
}
public double getLastBalance()
{
return lastBalance;
}
public int getAccountStatus()
{
return accountStatus;
}
public void setName(String n)
{
if (n.length() > MAX_NAME_LENGTH)
throw new IllegalArgumentException("Too Many Characters");
else
name = n;
}
public void setCardVendor(String v)
{
if (v.length() > MAX_VENDOR_LENGTH)
throw new IllegalArgumentException("Too Many Characters");
else
cardVendor = v;
}
public void setDateOpened(String d)
{
dateOpened = d;
}
public void setLastBalance(double b)
{
lastBalance = b;
}
public void setAccountStatus(int s)
{
accountStatus = s;
}
public String toString()
{
return String.format("%-25s %-15s $%-s %-s %-s",
name, cardVendor, lastBalance, dateOpened, accountStatus);
}
}
public class CardInfoNode
{
CardInfo thisCard;
CardInfoNode next;
CardInfoNode prev;
CardInfoNode()
{
}
public void setCardInfo(CardInfo info)
{
thisCard.setName(info.getName());
thisCard.setCardVendor(info.getCardVendor());
thisCard.setLastBalance(info.getLastBalance());
thisCard.setDateOpened(info.getDateOpened());
thisCard.setAccountStatus(info.getAccountStatus());
}
public CardInfo getInfo()
{
return thisCard;
}
public void setNext(CardInfoNode node)
{
next = node;
}
public void setPrev(CardInfoNode node)
{
prev = node;
}
public CardInfoNode getNext()
{
return next;
}
public CardInfoNode getPrev()
{
return prev;
}
}
public class CardList
{
CardInfoNode head;
CardInfoNode current;
CardInfoNode tail;
CardList()
{
head = current = tail = null;
}
public void insertCardInfo(CardInfo info)
{
if(head == null)
{
head = new CardInfoNode();
head.setCardInfo(info);
head.setNext(tail);
tail.setPrev(node) // here lies the problem. tail must be set to something
// to make it doubly-linked. but tail is null since it's
// and end point of the list.
}
}
}
Here is the assignment itself if it helps to clarify what is required and more importantly, the parts I'm not understanding. Thanks
https://docs.google.com/open?id=0B3vVwsO0eQRaQlRSZG95eXlPcVE
if(head == null)
{
head = new CardInfoNode();
head.setCardInfo(info);
head.setNext(tail);
tail.setPrev(node) // here lies the problem. tail must be set to something
// to make it doubly-linked. but tail is null since it's
// and end point of the list.
}
the above code is for when u not have any nodes in list, here u r going to add nodes to ur list.I.e. ist node to list
here u r pointing head & tail to same node
I assume CardList is meant to encapsulate the actual doubly-linked-list implementation.
Consider the base case of a DLL with only a single node: the node's prev and next references will be null (or itself). The list's encapsulation's head and tail references will both be the single node (as the node is both the start and end of the list). What's so difficult to understand about that?
NB: Assuming that CardList is an encapsulation of the DLL structure (rather than an operation) there's no reason for it to have a CardInfoNode current field, as that kind of state information is only useful to algorithms that work on the structure, which would be maintaining that themselves (it also makes your class thread-unsafe).

Categories