/******************************************************************************* * Copyright (c) 2012-present Jakub Kováč, Jozef Brandýs, Katarína Kotrlová, * Pavol Lukča, Ladislav Pápay, Viktor Tomkovič, Tatiana Tóthová * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package algvis.ds.priorityqueues.daryheap; import java.awt.Color; import java.util.Hashtable; import java.util.Vector; import algvis.core.DataStructure; import algvis.core.Node; import algvis.core.history.HashtableStoreSupport; import algvis.core.visual.ZDepth; import algvis.ds.priorityqueues.PriorityQueue; import algvis.ds.priorityqueues.heap.HeapNode; import algvis.ui.view.View; public class DaryHeapNode extends HeapNode { private int width;// , leftw, rightw; private DaryHeapNode parent = null; int nson = -1; // kolky je to syn svojho otca protected Vector<DaryHeapNode> c; int nnodes = 1; private int height = 1; // pre setStats private DaryHeapNode(DaryHeap D, int key, int x, int y, int zDepth) { super(D, key, x, y, zDepth); bgKeyColor(); c = new Vector<DaryHeapNode>(D.getOrder()); // setColor(NodeColor.NORMAL); width = DaryHeap.minsepx; // mark(); } public DaryHeapNode(DaryHeap D, int key, int zDepth) { this(D, key, 0, Node.UPY, zDepth); } public DaryHeapNode(DaryHeapNode v) { this((DaryHeap) v.D, v.getKey(), v.tox, v.toy, ZDepth.ACTIONNODE); } @Override public boolean isRoot() { return parent == null; } @Override public boolean isLeaf() { return c.isEmpty(); } /* * public boolean isLeft() { return parent.left==this; } public void * linkleft(BSTNode v) { left = v; v.parent = this; } public void * linkright(BSTNode v) { right = v; v.parent = this; } public void * isolate() { left = right = parent = null; } */ @Override public void calcTree() { nnodes = 1; for (final DaryHeapNode node : c) { node.calcTree(); nnodes += node.nnodes; } height = 1 + (isLeaf() ? 0 : c.get(0).height); } /* * public void addLeaf(int x) { c[numChildren++].key = x; for (int i = * numChildren - 1; i > 0; --i) { if (c[i].key < c[i - 1].key) { int tmp = * c[i].key; c[i].key = c[i - 1].key; c[i - 1].key = tmp; } } width = * _width(); } */ public int order() { for (int i = 0; i < parent.c.size(); ++i) { if (getParent().c.get(i) == this) { return i; } } return -5; // TODO: vypindat exception } /* * int _width() { * * if (key != Node.NOKEY && numChildren > 0) { return (2 * Node.radius + * DaryHeap.minsepx)*numChildren - DaryHeap.minsepx; } else { return * 2*Node.radius; } } */ @Override public void drawTree(View v) { drawTree2(v); } private void drawTree2(View v) { if (state != INVISIBLE) {// && !thread) { /* * if (thread) { v.setColor(Color.yellow); } else { */ v.setColor(Color.black); // } for (final DaryHeapNode node : c) { v.drawLine(x, y, node.x, node.y); } } for (final DaryHeapNode node : c) { node.drawTree2(v); } /* * v.setColor(Color.LIGHT_GRAY); ++i; v.drawLine(x, y, x, -20); * v.drawString("" + i, x, -23, 10); */ draw(v); } /* * public void drawTree(View v) { for (int i = 0; i < numChildren; ++i) { * v.setColor(Color.black); /* int xx, yy; if (i==0 || i==numChildren-1) { * xx = x; yy = y; } else { xx = (pos(i-1)+pos(i))/2; yy = y+D.radius; } *//* * v.drawLine(x, y, c[i].x, c[i].y - Node.radius); c[i].drawTree(v); } * draw(v); } */ @Override public void moveTree() { for (final DaryHeapNode node : c) { node.moveTree(); } move(); } @Override public void reboxTree() { for (final DaryHeapNode node : c) { node.reboxTree(); } rebox(); } @Override public void rebox() { leftw = 0; // -DaryHeap.minsepx / 2; rightw = 0; // -DaryHeap.minsepx / 2; if (isLeaf()) { leftw = DaryHeap.minsepx / 2; rightw = DaryHeap.minsepx / 2; width = leftw + rightw; return; } if (c.size() < ((DaryHeap) D).getOrder()) { leftw = (((DaryHeap) D).getOrder() / 2) * DaryHeap.minsepx; if (((DaryHeap) D).getOrder() % 2 == 1) { leftw += (DaryHeap.minsepx / 2); } if (c.size() > ((DaryHeap) D).getOrder() / 2) { rightw = leftw - (((DaryHeap) D).getOrder() - c.size()) * DaryHeap.minsepx; } else { rightw = DaryHeap.minsepx / 2; } width = leftw + rightw; return; } leftw = 0; rightw = 0; for (int i = 1; i <= ((DaryHeap) D).getOrder() / 2; i++) { leftw += c.get(i - 1).width; } for (int i = (((DaryHeap) D).getOrder() / 2) + 1; i <= ((DaryHeap) D) .getOrder(); i++) { rightw += c.get(i - 1).width; } if (((DaryHeap) D).getOrder() % 2 == 1) { rightw -= c.get(((DaryHeap) D).getOrder() / 2).leftw; leftw += c.get(((DaryHeap) D).getOrder() / 2).leftw; } width = leftw + rightw; } private void repos() { if (isRoot()) { goToRoot(); D.x1 = -width / 2; // -leftw; D.x2 = width / 2; // rightw; D.y2 = this.toy; } if (this.toy > D.y2) { D.y2 = this.toy; } /* * if (numChildren == 0) { return; } */ for (int i = 0; i < c.size(); i++) { if (i == 0) { c.firstElement().goTo( this.tox - (this.leftw) + c.firstElement().leftw, this.toy + DataStructure.minsepy); } else { c.get(i).goTo( c.get(i - 1).tox + c.get(i - 1).rightw + c.get(i).leftw, this.toy + DataStructure.minsepy); } c.get(i).repos(); } } public void _reposition() { reboxTree(); repos(); } @Override public DaryHeapNode getParent() { return parent; } void setParent(DaryHeapNode v) { this.parent = v; } public boolean prec(DaryHeapNode v) { if (((PriorityQueue) D).minHeap) { return this.getKey() < v.getKey(); } else { return this.getKey() > v.getKey(); } } /** * Precedes or equals (see prec). */ public boolean preceq(DaryHeapNode v) { if (((PriorityQueue) D).minHeap) { return this.getKey() <= v.getKey(); } else { return this.getKey() >= v.getKey(); } } // vracia otca najblizsieho suseda vpravo // funguje iba pre listy public DaryHeapNode nextNeighbour() { if (isRoot()) { return this; } if (getParent().c.size() < ((DaryHeap) D).getOrder()) { // pre root // nson == // -1 // System.out.print("malo synov kluca " + getParent().key + // ", konkretne " + getParent().numChildren + " a order mame prave " // + ((DaryHeap) D).getOrder() + "\n" ); return getParent(); } // if (this.nson == ((DaryHeap) D).getOrder()){ DaryHeapNode v = this; while ((!v.isRoot()) && (v.nson == ((DaryHeap) D).getOrder())) { v = v.getParent(); } if (v.isRoot()) { while (!v.c.isEmpty()) { v = v.c.firstElement(); } return v; } v = v.getParent().c.get(v.nson); // v poli je n-ty syn na mieste (nson - // 1) while (!v.c.isEmpty()) { v = v.c.firstElement(); } return v; // } // return this.getParent(); } // vracia najblizsieho suseda vlavo, (prerobit na otca?) // funguje iba pre listy public DaryHeapNode prevneighbour() { if (isRoot()) { return null; } if (nson > 1) { // pre root nson == -1 // System.out.print("dost synov, konkretne " + // getParent().numChildren + " a order mame prave " + ((DaryHeap) // D).getOrder() + "\n" ); return getParent().c.get(nson - 2); } DaryHeapNode v = this; while ((!v.isRoot()) && (v.nson == 1)) { v = v.getParent(); } if (!v.isRoot()) { v = v.getParent().c.get(v.nson - 2); } while ((v.c.get(((DaryHeap) D).getOrder() - 1) != null)) { // !v.isLeaf() v = v.c.get(((DaryHeap) D).getOrder() - 1); } return v; } public void linkNewSon(DaryHeapNode v) { v.setParent(this); c.add(v); v.nson = c.size(); ((DaryHeap) D).last = v; } @Override public DaryHeapNode find(int x, int y) { if (inside(x, y)) { return this; } for (final DaryHeapNode node : c) { final DaryHeapNode tmp = node.find(x, y); if (tmp != null) { return tmp; } } return null; } public DaryHeapNode findMaxSon() { DaryHeapNode v = c.firstElement(); for (final DaryHeapNode node : c) { if (node.prec(v)) { v = node; } } return v; } @Override public void storeState(Hashtable<Object, Object> state) { super.storeState(state); HashtableStoreSupport.store(state, hash + "parent", parent); HashtableStoreSupport.store(state, hash + "c", c.clone()); for (final DaryHeapNode node : c) { node.storeState(state); } HashtableStoreSupport.store(state, hash + "nson", nson); } @Override public void restoreState(Hashtable<?, ?> state) { super.restoreState(state); final Object parent = state.get(hash + "parent"); if (parent != null) { this.parent = (DaryHeapNode) HashtableStoreSupport.restore(parent); } final Object c = state.get(hash + "c"); if (c != null) { this.c = (Vector<DaryHeapNode>) HashtableStoreSupport.restore(c); } for (final DaryHeapNode node : this.c) { node.restoreState(state); } final Object nson = state.get(hash + "nson"); if (nson != null) { this.nson = (Integer) HashtableStoreSupport.restore(nson); } } }