A queue is a FIFO structure (First In, First Out).
16 | */ 17 | public class ArrayedQueue implements Collection 18 | { 19 | private var _que:Array; 20 | private var _size:int; 21 | private var _divisor:int; 22 | 23 | private var _count:int; 24 | private var _front:int; 25 | 26 | /** 27 | * Initializes a queue object to match the given size. 28 | * The size must be a power of two to use fast bitwise AND modulo. 29 | * 30 | * @param sizeShift The size exponent. (e.g. size is 1 << sizeShift eq. 2^sizeShift) 31 | */ 32 | public function ArrayedQueue(sizeShift:int) 33 | { 34 | if (sizeShift < 3) sizeShift = 3; 35 | _size = 1 << sizeShift; 36 | _divisor = _size - 1; 37 | clear(); 38 | } 39 | 40 | /** 41 | * Indicates the front item. 42 | * 43 | * @return The front item. 44 | */ 45 | public function peek():* 46 | { 47 | return _que[_front]; 48 | } 49 | 50 | /** 51 | * Enqueues some data. 52 | * 53 | * @param obj The data. 54 | * @return True if operation succeeded, otherwise false (queue is full). 55 | */ 56 | public function enqueue(obj:*):Boolean 57 | { 58 | if (_size != _count) 59 | { 60 | _que[int((_count++ + _front) & _divisor)] = obj; 61 | return true; 62 | } 63 | return false; 64 | } 65 | 66 | /** 67 | * Dequeues and returns the front item. 68 | * 69 | * @return The front item or null if the queue is empty. 70 | */ 71 | public function dequeue():* 72 | { 73 | if (_count > 0) 74 | { 75 | var data:* = _que[_front++]; 76 | if (_front == _size) _front = 0; 77 | _count--; 78 | return data; 79 | } 80 | return null; 81 | } 82 | 83 | /** 84 | * Deletes the last dequeued item to free it 85 | * for the garbage collector. Use only directly 86 | * after calling the dequeue() function. 87 | */ 88 | public function dispose():void 89 | { 90 | if (!_front) _que[int(_size - 1)] = null; 91 | else _que[int(_front - 1)] = null; 92 | } 93 | 94 | /** 95 | * Reads an item relative to the front index. 96 | * 97 | * @param i The index of the item. 98 | * @return The item at the given relative index. 99 | */ 100 | public function getAt(i:int):* 101 | { 102 | if (i >= _count) return null; 103 | return _que[int((i + _front) & _divisor)]; 104 | } 105 | 106 | /** 107 | * Writes an item relative to the front index. 108 | * 109 | * @param i The index of the item. 110 | * @param obj The data. 111 | */ 112 | public function setAt(i:int, obj:*):void 113 | { 114 | if (i >= _count) return; 115 | _que[int((i + _front) & _divisor)] = obj; 116 | } 117 | 118 | /** 119 | * Checks if a given item exists. 120 | * 121 | * @return True if the item is found, otherwise false. 122 | */ 123 | public function contains(obj:*):Boolean 124 | { 125 | for (var i:int = 0; i < _count; i++) 126 | { 127 | if (_que[int((i + _front) & _divisor)] === obj) 128 | return true; 129 | } 130 | return false; 131 | } 132 | 133 | /** 134 | * Clears all elements. 135 | */ 136 | public function clear():void 137 | { 138 | _que = new Array(_size); 139 | _front = _count = 0; 140 | } 141 | 142 | /** 143 | * Creates a new iterator pointing to the front of the queue. 144 | */ 145 | public function getIterator():Iterator 146 | { 147 | return new ArrayedQueueIterator(this); 148 | } 149 | 150 | /** 151 | * The total number of items in the queue. 152 | */ 153 | public function get size():int 154 | { 155 | return _count; 156 | } 157 | 158 | /** 159 | * Checks if the queue is empty. 160 | */ 161 | public function isEmpty():Boolean 162 | { 163 | return _count == 0; 164 | } 165 | 166 | /** 167 | * The maximum allowed size. 168 | */ 169 | public function get maxSize():int 170 | { 171 | return _size; 172 | } 173 | 174 | /** 175 | * Converts the structure into an array. 176 | * 177 | * @return An array. 178 | */ 179 | public function toArray():Array 180 | { 181 | var a:Array = new Array(_count); 182 | for (var i:int = 0; i < _count; i++) 183 | a[i] = _que[int((i + _front) & _divisor)]; 184 | return a; 185 | } 186 | 187 | /** 188 | * Returns a string representing the current object. 189 | */ 190 | public function toString():String 191 | { 192 | return "[ArrayedQueue, size=" + size + "]"; 193 | } 194 | 195 | /** 196 | * Prints out all elements in the queue (for debug/demo purposes). 197 | */ 198 | public function dump():String 199 | { 200 | var s:String = "[ArrayedQueue]\n"; 201 | 202 | s += "\t" + getAt(i) + " -> front\n"; 203 | for (var i:int = 1; i < _count; i++) 204 | s += "\t" + getAt(i) + "\n"; 205 | 206 | return s; 207 | } 208 | } 209 | } 210 | 211 | import de.polygonal.ds.Iterator; 212 | import de.polygonal.ds.ArrayedQueue; 213 | 214 | internal class ArrayedQueueIterator implements Iterator 215 | { 216 | private var _que:ArrayedQueue; 217 | private var _cursor:int; 218 | 219 | public function ArrayedQueueIterator(que:ArrayedQueue) 220 | { 221 | _que = que; 222 | _cursor = 0; 223 | } 224 | 225 | public function get data():* 226 | { 227 | return _que.getAt(_cursor); 228 | } 229 | 230 | public function set data(obj:*):void 231 | { 232 | _que.setAt(_cursor, obj); 233 | } 234 | 235 | public function start():void 236 | { 237 | _cursor = 0; 238 | } 239 | 240 | public function hasNext():Boolean 241 | { 242 | return _cursor < _que.size; 243 | } 244 | 245 | public function next():* 246 | { 247 | if (_cursor < _que.size) 248 | return _que.getAt(_cursor++); 249 | return null; 250 | } 251 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/ArrayedStack.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Collection; 12 | 13 | /** 14 | * An arrayed stack. 15 | *A stack is a LIFO structure (Last In, First Out).
16 | */ 17 | public class ArrayedStack implements Collection 18 | { 19 | private var _stack:Array; 20 | private var _size:int; 21 | private var _top:int; 22 | 23 | /** 24 | * Initializes a stack to match the given size. 25 | * 26 | * @param size The total number of elements the stack can store. 27 | */ 28 | public function ArrayedStack(size:int) 29 | { 30 | _size = size; 31 | clear(); 32 | } 33 | 34 | /** 35 | * Indicates the top item. 36 | * 37 | * @return The top item. 38 | */ 39 | public function peek():* 40 | { 41 | return _stack[int(_top - 1)]; 42 | } 43 | 44 | /** 45 | * Pushes data onto the stack. 46 | * 47 | * @param obj The data. 48 | */ 49 | public function push(obj:*):Boolean 50 | { 51 | if (_size != _top) 52 | { 53 | _stack[_top++] = obj; 54 | return true; 55 | } 56 | return false; 57 | } 58 | 59 | /** 60 | * Pops data from the stack. 61 | * 62 | * @return The top item. 63 | */ 64 | public function pop():void 65 | { 66 | if (_top > 0) _top-- 67 | } 68 | 69 | /** 70 | * Reads an item at a given index. 71 | * 72 | * @param i The index. 73 | * @return The item at the given index. 74 | */ 75 | public function getAt(i:int):* 76 | { 77 | if (i >= _top) return null; 78 | return _stack[i]; 79 | } 80 | 81 | /** 82 | * Writes an item at a given index. 83 | * 84 | * @param i The index. 85 | * @param obj The data. 86 | */ 87 | public function setAt(i:int, obj:*):void 88 | { 89 | if (i >= _top) return; 90 | _stack[i] = obj; 91 | } 92 | 93 | /** 94 | * Checks if a given item exists. 95 | * 96 | * @return True if the item is found, otherwise false. 97 | */ 98 | public function contains(obj:*):Boolean 99 | { 100 | for (var i:int = 0; i < _top; i++) 101 | { 102 | if (_stack[i] === obj) 103 | return true; 104 | } 105 | return false; 106 | } 107 | 108 | /** 109 | * Clears the stack. 110 | */ 111 | public function clear():void 112 | { 113 | _stack = new Array(_size); 114 | _top = 0; 115 | } 116 | 117 | /** 118 | * Creates a new iterator pointing to the top item. 119 | */ 120 | public function getIterator():Iterator 121 | { 122 | return new ArrayedStackIterator(this); 123 | } 124 | 125 | /** 126 | * The total number of items in the stack. 127 | */ 128 | public function get size():int 129 | { 130 | return _top; 131 | } 132 | 133 | /** 134 | * Checks if the stack is empty. 135 | */ 136 | public function isEmpty():Boolean 137 | { 138 | return _size == 0; 139 | } 140 | 141 | /** 142 | * The maximum allowed size. 143 | */ 144 | public function get maxSize():int 145 | { 146 | return _size; 147 | } 148 | 149 | /** 150 | * Converts the structure into an array. 151 | * 152 | * @return An array. 153 | */ 154 | public function toArray():Array 155 | { 156 | return _stack.concat(); 157 | } 158 | 159 | /** 160 | * Returns a string representing the current object. 161 | */ 162 | public function toString():String 163 | { 164 | return "[ArrayedStack, size= " + _top + "]"; 165 | } 166 | 167 | /** 168 | * Prints out all elements in the queue (for debug/demo purposes). 169 | */ 170 | public function dump():String 171 | { 172 | var s:String = "[ArrayedStack]"; 173 | if (_top == 0) return s; 174 | 175 | var k:int = _top - 1; 176 | s += "\n\t" + _stack[k--] + " -> front\n"; 177 | for (var i:int = k; i >= 0; i--) 178 | s += "\t" + _stack[i] + "\n"; 179 | return s; 180 | } 181 | } 182 | } 183 | 184 | import de.polygonal.ds.Iterator; 185 | import de.polygonal.ds.ArrayedStack; 186 | 187 | internal class ArrayedStackIterator implements Iterator 188 | { 189 | private var _stack:ArrayedStack; 190 | private var _cursor:int; 191 | 192 | public function ArrayedStackIterator(stack:ArrayedStack) 193 | { 194 | _stack = stack; 195 | start(); 196 | } 197 | 198 | public function get data():* 199 | { 200 | return _stack.getAt(_cursor); 201 | } 202 | 203 | public function set data(obj:*):void 204 | { 205 | _stack.setAt(_cursor, obj); 206 | } 207 | 208 | public function start():void 209 | { 210 | _cursor = _stack.size - 1; 211 | } 212 | 213 | public function hasNext():Boolean 214 | { 215 | return _cursor >= 0; 216 | } 217 | 218 | public function next():* 219 | { 220 | if (_cursor >= 0) 221 | return _stack.getAt(_cursor--); 222 | return null; 223 | } 224 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/BinarySearchTree.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Collection; 12 | import de.polygonal.ds.NullIterator; 13 | import de.polygonal.ds.BinaryTreeNode; 14 | 15 | /** 16 | * A Binary Search Tree (BST). 17 | * 18 | *A BST stores data in a recursive manner so that you can
19 | * access it quickly by using a key. Therefore, a BST automatically
20 | * sorts data as it is inserted.
21 | * For a BST to be valid, every node has to follow two rules:
A Binary Tree is a simplified tree structure in which every node is 15 | * only allowed to have up to two children nodes, which are called 16 | * the left and right child.
17 | */ 18 | public class BinaryTreeNode 19 | { 20 | /** 21 | * Performs a preorder traversal on a tree. 22 | * This processes the current tree node before its children. 23 | * 24 | * @param node The node to start from. 25 | * @param process A process function applied to each traversed node. 26 | */ 27 | public static function preorder(node:BinaryTreeNode, process:Function):void 28 | { 29 | if (node) 30 | { 31 | process(node); 32 | 33 | if (node.left) 34 | BinaryTreeNode.preorder(node.left, process); 35 | 36 | if (node.right) 37 | BinaryTreeNode.preorder(node.right, process); 38 | } 39 | } 40 | 41 | /** 42 | * Performs an inorder traversal on a tree. 43 | * This processes the current node in between the children nodes. 44 | * 45 | * @param node The node to start from. 46 | * @param process A process function applied to each traversed node. 47 | */ 48 | public static function inorder(node:BinaryTreeNode, process:Function):void 49 | { 50 | if (node) 51 | { 52 | if (node.left) 53 | BinaryTreeNode.inorder(node.left, process); 54 | 55 | process(node); 56 | 57 | if (node.right) 58 | BinaryTreeNode.inorder(node.right, process); 59 | } 60 | } 61 | 62 | /** 63 | * Performs a postorder traversal on a tree. 64 | * This processes the current node after its children nodes. 65 | * 66 | * @param node The node to start from. 67 | * @param process A process function applied to each traversed node. 68 | */ 69 | public static function postorder(node:BinaryTreeNode, process:Function):void 70 | { 71 | if (node) 72 | { 73 | if (node.left) 74 | BinaryTreeNode.postorder(node.left, process); 75 | 76 | if (node.right) 77 | BinaryTreeNode.postorder(node.right, process); 78 | 79 | process(node); 80 | } 81 | } 82 | 83 | /** 84 | * The left child node being referenced. 85 | */ 86 | public var left:BinaryTreeNode; 87 | 88 | /** 89 | * The right child node being referenced. 90 | */ 91 | public var right:BinaryTreeNode; 92 | 93 | /** 94 | * The parent node being referenced. 95 | */ 96 | public var parent:BinaryTreeNode; 97 | 98 | /** 99 | * The node's data. 100 | */ 101 | public var data:*; 102 | 103 | /** 104 | * Creates an empty node. 105 | * 106 | * @param obj The data to store inside the node. 107 | */ 108 | public function BinaryTreeNode(obj:*) 109 | { 110 | this.data = data; 111 | parent = left = right = null; 112 | } 113 | 114 | /** 115 | * Writes data into the left child. 116 | * 117 | * @param obj The data. 118 | */ 119 | public function setLeft(obj:*):void 120 | { 121 | if (!left) 122 | { 123 | left = new BinaryTreeNode(obj); 124 | left.parent = this; 125 | } 126 | else 127 | left.data = data; 128 | } 129 | 130 | /** 131 | * Writes data into the right child. 132 | * 133 | * @param obj The data. 134 | */ 135 | public function setRight(obj:*):void 136 | { 137 | if (!right) 138 | { 139 | right = new BinaryTreeNode(obj); 140 | right.parent = this; 141 | } 142 | else 143 | right.data = data; 144 | } 145 | 146 | /** 147 | * Checks if this node is left of its parent. 148 | * 149 | * @return True if this node is left, otherwise false. 150 | */ 151 | public function isLeft():Boolean 152 | { 153 | return this == parent.left; 154 | } 155 | 156 | 157 | /** 158 | * Check if this node is a right of its parent. 159 | * 160 | * @return True if this node is right, otherwise false. 161 | */ 162 | public function isRight():Boolean 163 | { 164 | return this == parent.right; 165 | } 166 | 167 | /** 168 | * Recursively calculates the depth of a tree. 169 | * 170 | * @return The depth of the tree. 171 | */ 172 | public function getDepth(node:BinaryTreeNode = null):int 173 | { 174 | var left:int = -1, right:int = -1; 175 | 176 | if (node == null) node = this; 177 | 178 | if (node.left) 179 | left = getDepth(node.left); 180 | 181 | if (node.right) 182 | right = getDepth(node.right); 183 | 184 | return (Math.max(left, right) + 1); 185 | } 186 | 187 | /** 188 | * Recursively counts the total number 189 | * of nodes including this node. 190 | */ 191 | public function count():int 192 | { 193 | var c:int = 1; 194 | 195 | if (left) 196 | c += left.count(); 197 | 198 | if (right) 199 | c += right.count(); 200 | 201 | return c; 202 | } 203 | 204 | /** 205 | * Recursively clears the tree by deleting 206 | * all child nodes underneath the node 207 | * the method is called on. 208 | */ 209 | public function destroy():void 210 | { 211 | if (left) 212 | left.destroy(); 213 | 214 | left = null; 215 | 216 | if (right) 217 | right.destroy(); 218 | 219 | right = null; 220 | } 221 | 222 | /** 223 | * Returns a string representing the current object. 224 | */ 225 | public function toString():String 226 | { 227 | return "[BinaryTreeNode, data= " + data + "]"; 228 | } 229 | } 230 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/BitVector.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | /** 12 | * A bitvector. 13 | * 14 | * A bitvector is meant to condense bit values (or booleans) into 15 | * an array as close as possible so that no space is wasted. 16 | */ 17 | public class BitVector 18 | { 19 | private var _bits:Array; 20 | private var _arrSize:int; 21 | private var _bitSize:int; 22 | 23 | /** 24 | * Creates a bitvector with a given number of bits. 25 | * Each cell holds a 31-bit signed integer. 26 | * 27 | * @param bits The total number of bits. 28 | */ 29 | public function BitVector(bits:int) 30 | { 31 | _bits = []; 32 | _arrSize = 0; 33 | 34 | resize(bits); 35 | } 36 | 37 | /** 38 | * The total number of bits. 39 | */ 40 | public function get bitCount():int 41 | { 42 | return _arrSize * 31; 43 | } 44 | 45 | /** 46 | * The total number of cells. 47 | */ 48 | public function get cellCount():int 49 | { 50 | return _arrSize; 51 | } 52 | 53 | /** 54 | * Gets a bit from a given index. 55 | * 56 | * @param index The index of the bit. 57 | */ 58 | public function getBit(index:int):int 59 | { 60 | var bit:int = index % 31; 61 | return (_bits[(index / 31) >> 0] & (1 << bit)) >> bit; 62 | } 63 | 64 | /** 65 | * Sets a bit at a given index. 66 | * 67 | * @param index The index of the bit. 68 | * @param b The boolean flag to set. 69 | */ 70 | public function setBit(index:int, b:Boolean):void 71 | { 72 | var cell:int = index / 31; 73 | var mask:int = 1 << index % 31; 74 | _bits[cell] = b ? (_bits[cell] | mask) : (_bits[cell] & (~mask)); 75 | } 76 | 77 | /** 78 | * Resizes the bitvector to an appropriate number of bits. 79 | * 80 | * @param size The total number of bits. 81 | */ 82 | public function resize(size:int):void 83 | { 84 | if (size == _bitSize) return; 85 | _bitSize = size; 86 | 87 | //convert the bit-size to integer-size 88 | if (size % 31 == 0) 89 | size /= 31; 90 | else 91 | size = (size / 31) + 1; 92 | 93 | if (size < _arrSize) 94 | { 95 | _bits.splice(size); 96 | _arrSize = size; 97 | } 98 | else 99 | { 100 | _bits = _bits.concat(new Array(size - _arrSize)); 101 | _arrSize = _bits.length; 102 | } 103 | } 104 | 105 | /** 106 | * Resets all bits to 0; 107 | */ 108 | public function clear():void 109 | { 110 | var k:int = _bits.length; 111 | for (var i:int = 0; i < k; i++) 112 | _bits[i] = 0; 113 | } 114 | 115 | /** 116 | * Sets each bit to 1. 117 | */ 118 | public function setAll():void 119 | { 120 | var k:int = _bits.length; 121 | for (var i:int = 0; i < k; i++) 122 | _bits[i] = int.MAX_VALUE; 123 | } 124 | 125 | /** 126 | * Returns a string representing the current object. 127 | */ 128 | public function toString():String 129 | { 130 | return "[BitVector, size=" + _bitSize + "]"; 131 | } 132 | } 133 | } 134 | 135 | -------------------------------------------------------------------------------- /src/de/polygonal/ds/Collection.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Iterator; 12 | 13 | /** 14 | * A 'java-style' collection interface. 15 | */ 16 | public interface Collection 17 | { 18 | /** 19 | * Searches the collection for a matching item. 20 | * 21 | * @return True if the item exists, otherwise false. 22 | */ 23 | function contains(obj:*):Boolean 24 | 25 | /** 26 | * Clears all items. 27 | */ 28 | function clear():void 29 | 30 | /** 31 | * Initializes an iterator object pointing 32 | * to the first item in the collection. 33 | * 34 | * @return An iterator object. 35 | */ 36 | function getIterator():Iterator 37 | 38 | /** 39 | * The total number of items. 40 | * 41 | * @return The size. 42 | */ 43 | function get size():int; 44 | 45 | /** 46 | * Checks if the collection is empty. 47 | * 48 | * @return True if empty, otherwise false. 49 | */ 50 | function isEmpty():Boolean 51 | 52 | /** 53 | * Converts the collection into an array. 54 | * 55 | * @return An array. 56 | */ 57 | function toArray():Array 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/de/polygonal/ds/DLinkedList.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Iterator; 12 | import de.polygonal.ds.Collection; 13 | 14 | import de.polygonal.ds.DListNode; 15 | import de.polygonal.ds.DListIterator; 16 | 17 | /** 18 | * A doubly linked list. 19 | * 20 | *A doubly linked list stores a reference to the next 21 | * and previous node which makes it possible to traverse 22 | * the list in both directions.
23 | */ 24 | public class DLinkedList implements Collection 25 | { 26 | private var _count:int; 27 | 28 | /** 29 | * The head node being referenced. 30 | */ 31 | public var head:DListNode; 32 | 33 | /** 34 | * The tail node being referenced. 35 | */ 36 | public var tail:DListNode; 37 | 38 | /** 39 | * Initializes an empty list. 40 | */ 41 | public function DLinkedList() 42 | { 43 | head = tail = null; 44 | _count = 0; 45 | } 46 | 47 | /** 48 | * Appends an item to the list. 49 | * 50 | * @param obj The data. 51 | * @return A doubly linked list node wrapping the data. 52 | */ 53 | public function append(obj:*):DListNode 54 | { 55 | var node:DListNode = new DListNode(obj); 56 | if (head) 57 | { 58 | tail.insertAfter(node); 59 | tail = tail.next; 60 | } 61 | else 62 | head = tail = node; 63 | 64 | _count++; 65 | return node; 66 | } 67 | 68 | /** 69 | * Prepends an item to the list. 70 | * 71 | * @param obj The data. 72 | * @return A doubly linked list node wrapping the data. 73 | */ 74 | public function prepend(obj:*):DListNode 75 | { 76 | var node:DListNode = new DListNode(obj); 77 | 78 | if (head) 79 | { 80 | head.insertBefore(node); 81 | head = head.prev; 82 | } 83 | else 84 | head = tail = node; 85 | 86 | _count++; 87 | return node; 88 | } 89 | 90 | /** 91 | * Inserts an item after a given iterator or appends it 92 | * if the iterator is invalid. 93 | * 94 | * @param itr A doubly linked list iterator. 95 | * @param obj The data. 96 | * @return A doubly linked list node wrapping the data. 97 | */ 98 | public function insertAfter(itr:DListIterator, obj:*):DListNode 99 | { 100 | if (itr.list != this) return null; 101 | if (itr.node) 102 | { 103 | var node:DListNode = new DListNode(obj); 104 | itr.node.insertAfter(node); 105 | 106 | if (itr.node == tail) 107 | tail = itr.node.next; 108 | 109 | _count++; 110 | return node; 111 | } 112 | else 113 | return append(obj); 114 | } 115 | 116 | /** 117 | * Inserts an item before a given iterator or appends it 118 | * if the iterator is invalid. 119 | * 120 | * @param itr A doubly linked list iterator. 121 | * @param obj The data. 122 | * @return A doubly linked list node wrapping the data. 123 | */ 124 | public function insertBefore(itr:DListIterator, obj:*):DListNode 125 | { 126 | if (itr.list != this) return null; 127 | if (itr.node) 128 | { 129 | var node:DListNode = new DListNode(obj); 130 | itr.node.insertBefore(node); 131 | if (itr.node == head) 132 | head = head.prev; 133 | 134 | _count++; 135 | return node; 136 | } 137 | else 138 | return prepend(obj); 139 | } 140 | 141 | /** 142 | * Removes the node the iterator is pointing 143 | * at and moves the iterator to the next node. 144 | * 145 | * @return True if the removal succeeded, otherwise false. 146 | */ 147 | public function remove(itr:DListIterator):Boolean 148 | { 149 | if (itr.list != this || !itr.node) return false; 150 | 151 | var node:DListNode = itr.node; 152 | 153 | if (node == head) 154 | head = head.next; 155 | else 156 | if (node == tail) 157 | tail = tail.prev; 158 | 159 | itr.forth(); 160 | node.unlink(); 161 | 162 | if (head == null) tail = null; 163 | 164 | _count--; 165 | return true; 166 | } 167 | 168 | /** 169 | * Removes the head of the list. 170 | */ 171 | public function removeHead():void 172 | { 173 | if (head) 174 | { 175 | head = head.next; 176 | 177 | if (head) 178 | head.prev = null; 179 | else 180 | tail = null 181 | 182 | _count--; 183 | } 184 | } 185 | 186 | /** 187 | * Removes the tail of the list. 188 | */ 189 | public function removeTail():void 190 | { 191 | if (tail) 192 | { 193 | tail = tail.prev; 194 | 195 | if (tail) 196 | tail.next = null; 197 | else 198 | head = null; 199 | 200 | _count--; 201 | } 202 | } 203 | 204 | /** 205 | * Checks if a given item exists. 206 | * 207 | * @return True if the item is found, otherwise false. 208 | */ 209 | public function contains(obj:*):Boolean 210 | { 211 | var node:DListNode = head; 212 | while (node) 213 | { 214 | if (node.data == obj) return true; 215 | node = node.next; 216 | } 217 | return false; 218 | } 219 | 220 | /** 221 | * Clears the list by unlinking all nodes 222 | * from it. This is important to unlock 223 | * the nodes for the garbage collector. 224 | */ 225 | public function clear():void 226 | { 227 | var node:DListNode = head; 228 | head = null; 229 | 230 | var next:DListNode; 231 | while (node) 232 | { 233 | next = node.next; 234 | node.next = node.prev = null; 235 | node = next; 236 | } 237 | _count = 0; 238 | } 239 | 240 | /** 241 | * Creates an iterator object pointing 242 | * at the first node in the list. 243 | * 244 | * @returns An iterator object. 245 | */ 246 | public function getIterator():Iterator 247 | { 248 | return new DListIterator(this, head); 249 | } 250 | 251 | /** 252 | * Creates a doubly linked iterator object pointing 253 | * at the first node in the list. 254 | * 255 | * @returns A DListIterator object. 256 | */ 257 | public function getListIterator():DListIterator 258 | { 259 | return new DListIterator(this, head); 260 | } 261 | 262 | /** 263 | * The total number of nodes in the list. 264 | */ 265 | public function get size():int 266 | { 267 | return _count; 268 | } 269 | 270 | /** 271 | * Checks if the list is empty. 272 | */ 273 | public function isEmpty():Boolean 274 | { 275 | return _count == 0; 276 | } 277 | 278 | /** 279 | * Converts the linked list into an array. 280 | * 281 | * @return An array. 282 | */ 283 | public function toArray():Array 284 | { 285 | var a:Array = []; 286 | var node:DListNode = head; 287 | while (node) 288 | { 289 | a.push(node.data); 290 | node = node.next; 291 | } 292 | return a; 293 | } 294 | 295 | /** 296 | * Returns a string representing the current object. 297 | */ 298 | public function toString():String 299 | { 300 | return "[DLinkedList > has " + size + " nodes]"; 301 | } 302 | 303 | /** 304 | * Prints out all elements in the list (for debug/demo purposes). 305 | */ 306 | public function dump():String 307 | { 308 | if (head == null) return "DLinkedList, empty"; 309 | 310 | var s:String = "DLinkedList, has " + _count + " node" + (_count == 1 ? "" : "s") + "\n|< Head\n"; 311 | 312 | var itr:DListIterator = getListIterator(); 313 | for (; itr.valid(); itr.forth()) 314 | s += "\t" + itr.data + "\n"; 315 | 316 | s += "Tail >|"; 317 | 318 | return s; 319 | } 320 | } 321 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/DListIterator.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.DListNode; 12 | import de.polygonal.ds.DLinkedList; 13 | 14 | /** 15 | * A list iterator. 16 | */ 17 | public class DListIterator implements Iterator 18 | { 19 | /** 20 | * The node the iterator is pointing to. 21 | */ 22 | public var node:DListNode; 23 | 24 | /** 25 | * The list of the iterator is referenced. 26 | */ 27 | public var list:DLinkedList; 28 | 29 | /** 30 | * Initializes a new DListIterator instance pointing to a given node. 31 | * Usually created by invoking SLinkedList.getIterator(). 32 | * 33 | * @param list The linked list the iterator should use. 34 | * @param node The iterator's initial node. 35 | */ 36 | public function DListIterator(list:DLinkedList, node:DListNode = null) 37 | { 38 | this.list = list; 39 | this.node = node; 40 | } 41 | 42 | /** 43 | * Moves the iterator to the start of the list. 44 | */ 45 | public function start():void 46 | { 47 | node = list.head; 48 | } 49 | 50 | /** 51 | * Returns the current node's data while 52 | * moving the iterator forward by one position. 53 | */ 54 | public function next():* 55 | { 56 | if (hasNext()) 57 | { 58 | var obj:* = node.data; 59 | node = node.next; 60 | return obj; 61 | } 62 | return null; 63 | } 64 | 65 | /** 66 | * Checks if the next node exists. 67 | */ 68 | public function hasNext():Boolean 69 | { 70 | return Boolean(node); 71 | } 72 | 73 | /** 74 | * Read/writes the current node's data. 75 | * 76 | * @return The data. 77 | */ 78 | public function get data():* 79 | { 80 | if (node) return node.data; 81 | return null; 82 | } 83 | 84 | public function set data(obj:*):void 85 | { 86 | node.data = obj; 87 | } 88 | 89 | /** 90 | * Moves the iterator to the end of the list. 91 | */ 92 | public function end():void 93 | { 94 | node = list.tail; 95 | } 96 | 97 | /** 98 | * Moves the iterator to the next node. 99 | */ 100 | public function forth():void 101 | { 102 | if (node) node = node.next; 103 | } 104 | 105 | /** 106 | * Moves the iterator to the previous node. 107 | */ 108 | public function back():void 109 | { 110 | if (node) node = node.prev; 111 | } 112 | 113 | /** 114 | * Checks if the current referenced node is valid. 115 | * 116 | * @return True if the node exists, otherwise false. 117 | */ 118 | public function valid():Boolean 119 | { 120 | return Boolean(node); 121 | } 122 | 123 | /** 124 | * Removes the node the iterator is 125 | * pointing to. 126 | */ 127 | public function remove():void 128 | { 129 | list.remove(this); 130 | } 131 | 132 | /** 133 | * Returns a string representing the current object. 134 | */ 135 | public function toString():String 136 | { 137 | return "{DListIterator, data=" + (node ? node.data : "null") + "}"; 138 | } 139 | } 140 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/DListNode.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | /** 12 | * A list node. 13 | * 14 | * The node acts as a data container and also 15 | * holds a reference to next and previous node 16 | * in the list. 17 | */ 18 | public class DListNode 19 | { 20 | /** 21 | * The node's data. 22 | */ 23 | public var data:*; 24 | 25 | /** 26 | * The next node in the list being referenced. 27 | */ 28 | public var next:DListNode; 29 | 30 | /** 31 | * The previous node in the list being referenced. 32 | */ 33 | public var prev:DListNode; 34 | 35 | /** 36 | * Initializes a new node that stores 37 | * the given item. 38 | * 39 | * @param obj The data to store in the node. 40 | */ 41 | public function DListNode(obj:*) 42 | { 43 | next = prev = null; 44 | data = obj; 45 | } 46 | 47 | /** 48 | * A helper function used solely by the DLinkedList class 49 | * for inserting this node after a given node. 50 | * 51 | * @param node A doubly linked list node. 52 | */ 53 | public function insertAfter(node:DListNode):void 54 | { 55 | node.next = next; 56 | node.prev = this; 57 | if (next) next.prev = node; 58 | next = node; 59 | } 60 | 61 | /** 62 | * A helper function used solely by the DLinkedList class 63 | * for inserting this node in front of a given node. 64 | * 65 | * @param node A doubly linked list node. 66 | */ 67 | public function insertBefore(node:DListNode):void 68 | { 69 | node.next = this; 70 | node.prev = prev; 71 | if (prev) prev.next = node; 72 | prev = node; 73 | } 74 | 75 | /** 76 | * A helper function used solely by the DLinkedList class 77 | * to unlink the node from the list. 78 | */ 79 | public function unlink():void 80 | { 81 | if (prev) prev.next = next; 82 | if (next) next.prev = prev; 83 | next = prev = null; 84 | } 85 | 86 | /** 87 | * Returns a string representing the current object. 88 | */ 89 | public function toString():String 90 | { 91 | return "[DListNode, data=" + data + "]" 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/Graph.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.GraphNode; 12 | 13 | /** 14 | * A linked uni-directional weighted graph structure. 15 | *The Graph class manages all graph nodes. Each graph node has 16 | * a linked list of arcs, pointing to different nodes.
17 | */ 18 | public class Graph 19 | { 20 | /** 21 | * An array containing all graph nodes. 22 | */ 23 | public var nodes:Array; 24 | 25 | private var _nodeCount:int; 26 | private var _maxSize:int; 27 | 28 | /** 29 | * Constructs an empty graph. 30 | * 31 | * @param size The total number of nodes allowed. 32 | */ 33 | public function Graph(size:int) 34 | { 35 | nodes = new Array(_maxSize = size); 36 | _nodeCount = 0; 37 | } 38 | 39 | /** 40 | * Performs a depth-first traversal on the given node. 41 | * 42 | * @param node The starting graph node. 43 | * @param process A function to apply to each traversed node. 44 | */ 45 | public function depthFirst(node:GraphNode, process:Function):void 46 | { 47 | if (!node) return; 48 | 49 | process(node); 50 | node.marked = true; 51 | 52 | var k:int = node.numArcs, t:GraphNode; 53 | for (var i:int = 0; i < k; i++) 54 | { 55 | t = node.arcs[i].node; 56 | if (!t.marked) depthFirst(t, process); 57 | } 58 | } 59 | 60 | /** 61 | * Performs a breadth-first traversal on the given node. 62 | * 63 | * @param node The starting graph node. 64 | * @param process A function to apply to each traversed node. 65 | */ 66 | public function breadthFirst(node:GraphNode, process:Function):void 67 | { 68 | if (!node) return; 69 | 70 | var que:Array = []; 71 | que.push(node); 72 | node.marked = true; 73 | 74 | var c:int = 1; 75 | 76 | var t:GraphNode, u:GraphNode; 77 | while (c > 0) 78 | { 79 | process(t = que[0]); 80 | 81 | var arcs:Array = t.arcs, k:int = t.numArcs; 82 | for (var i:int = 0; i < k; i++) 83 | { 84 | u = arcs[i].node; 85 | if (!u.marked) 86 | { 87 | u.marked = true; 88 | que.push(u); 89 | c++; 90 | } 91 | } 92 | que.shift(); 93 | c--; 94 | } 95 | } 96 | 97 | /** 98 | * Adds a node at a given index to the graph. 99 | * 100 | * @param obj The data to store in the node. 101 | * @param i The index the node is stored at. 102 | * @return True if successful, otherwise false. 103 | */ 104 | public function addNode(obj:*, i:int):Boolean 105 | { 106 | if (nodes[i]) return false; 107 | 108 | nodes[i] = new GraphNode(obj); 109 | _nodeCount++; 110 | return true; 111 | } 112 | 113 | /** 114 | * Removes a node from the graph at a given index. 115 | * 116 | * @param index Index of the node to remove 117 | * @return True if successful, otherwise false. 118 | */ 119 | public function removeNode(i:int):Boolean 120 | { 121 | var node:GraphNode = nodes[i]; 122 | if(!node) return false; 123 | 124 | var arc:GraphArc; 125 | for (var j:int = 0; j < _maxSize; j++) 126 | { 127 | var t:GraphNode = nodes[j]; 128 | if (t && t.getArc(node)) removeArc(j, i); 129 | } 130 | 131 | nodes[i] = null; 132 | _nodeCount--; 133 | return true; 134 | } 135 | 136 | /** 137 | * Finds an arc pointing to the node 138 | * at the 'from' index to the node at the 'to' index. 139 | * 140 | * @param from The originating graph node index. 141 | * @param to The ending graph node index. 142 | * @return A GraphArc object or null if it doesn't exist. 143 | */ 144 | public function getArc(from:int, to:int):GraphArc 145 | { 146 | var node0:GraphNode = nodes[from]; 147 | var node1:GraphNode = nodes[to]; 148 | if (node0 && node1) return node0.getArc(node1); 149 | return null; 150 | } 151 | 152 | /** 153 | * Adds an arc pointing to the node located at the 154 | * 'from' index to the node at the 'to' index. 155 | * 156 | * @param from The originating graph node index. 157 | * @param to The ending graph node index. 158 | * @param weight The arc's weight 159 | * 160 | * @return True if an arc was added, otherwise false. 161 | */ 162 | public function addArc(from:int, to:int, weight:int = 1):Boolean 163 | { 164 | var node0:GraphNode = nodes[from]; 165 | var node1:GraphNode = nodes[to]; 166 | 167 | if (node0 && node1) 168 | { 169 | if (node0.getArc(node1)) return false; 170 | 171 | node0.addArc(node1, weight); 172 | return true; 173 | } 174 | return false; 175 | } 176 | 177 | /** 178 | * Removes an arc pointing to the node located at the 179 | * 'from' index to the node at the 'to' index. 180 | * 181 | * @param from The originating graph node index. 182 | * @param to The ending graph node index. 183 | * 184 | * @return True if an arc was removed, otherwise false. 185 | */ 186 | public function removeArc(from:int, to:int):Boolean 187 | { 188 | var node0:GraphNode = nodes[from]; 189 | var node1:GraphNode = nodes[to]; 190 | 191 | if (node0 && node1) 192 | { 193 | node0.removeArc(node1); 194 | return true; 195 | } 196 | return false; 197 | } 198 | 199 | /** 200 | * Clears the markers on all nodes in the graph 201 | * so the breadth-first and depth-first traversal 202 | * algorithms can 'see' the nodes. 203 | */ 204 | public function clearMarks():void 205 | { 206 | for (var i:int = 0; i < _maxSize; i++) 207 | { 208 | var node:GraphNode = nodes[i]; 209 | if (node) node.marked = false; 210 | } 211 | } 212 | 213 | /** 214 | * The number of nodes in the graph. 215 | */ 216 | public function get size():int 217 | { 218 | return _nodeCount; 219 | } 220 | 221 | /** 222 | * The maximum number of nodes the 223 | * graph can store. 224 | */ 225 | public function get maxSize():int 226 | { 227 | return _maxSize; 228 | } 229 | 230 | /** 231 | * Clears every node in the graph. 232 | */ 233 | public function clear():void 234 | { 235 | nodes = new Array(_maxSize); 236 | _nodeCount = 0; 237 | } 238 | } 239 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/GraphArc.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | /** 12 | * A weighted arc pointing to a graph node. 13 | */ 14 | public class GraphArc 15 | { 16 | /** 17 | * The node that the arc points to being referenced. 18 | */ 19 | public var node:GraphNode; 20 | 21 | /** 22 | * The weight (or cost) of the arc. 23 | */ 24 | public var weight:Number 25 | 26 | /** 27 | * Initializes a new graph arc with a given weight. 28 | * 29 | * @param node The graph node. 30 | * @param weight The weight. 31 | */ 32 | public function GraphArc(node:GraphNode, weight:Number = 1) 33 | { 34 | this.node = node; 35 | this.weight = weight; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/GraphNode.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.GraphArc; 12 | 13 | /** 14 | * A graph node. 15 | */ 16 | public class GraphNode 17 | { 18 | /** 19 | * The data being referenced. 20 | */ 21 | public var data:*; 22 | 23 | /** 24 | * An array of arcs connecting this node to other nodes. 25 | */ 26 | public var arcs:Array; 27 | 28 | /** 29 | * A flag indicating whether the node is marked or not. 30 | * Used for iterating over a graph structure. 31 | */ 32 | public var marked:Boolean; 33 | 34 | private var _arcCount:int = 0; 35 | 36 | /** 37 | * Constructs a new graph node. 38 | * 39 | * @param obj The data to store inside the node. 40 | */ 41 | public function GraphNode(obj:*) 42 | { 43 | this.data = obj; 44 | arcs = []; 45 | _arcCount = 0; 46 | marked = false; 47 | } 48 | 49 | /** 50 | * Adds an arc to the current graph node, pointing to a different 51 | * graph node and with a given weight. 52 | * 53 | * @param target The destination node the arc should point to. 54 | * @param weigth The arc's weigth. 55 | */ 56 | public function addArc(target:GraphNode, weight:Number):void 57 | { 58 | arcs.push(new GraphArc(target, weight)); 59 | _arcCount++; 60 | } 61 | 62 | /** 63 | * Removes the arc that points to the given node. 64 | * 65 | * @return True if removal was successful, otherwise false. 66 | */ 67 | public function removeArc(target:GraphNode):Boolean 68 | { 69 | for (var i:int = 0; i < _arcCount; i++) 70 | { 71 | if (arcs[i].node == target) 72 | { 73 | arcs.splice(i, 1); 74 | _arcCount--; 75 | return true; 76 | } 77 | } 78 | return false; 79 | } 80 | 81 | /** 82 | * Finds the arc that points to the given node. 83 | * 84 | * @param target The destination node. 85 | * 86 | * @return A GraphArc object or null if the arc doesn't exist. 87 | */ 88 | public function getArc(target:GraphNode):GraphArc 89 | { 90 | for (var i:int = 0 ; i < _arcCount; i++) 91 | { 92 | var arc:GraphArc = arcs[i]; 93 | if (arc.node == target) return arc; 94 | } 95 | return null; 96 | } 97 | 98 | /** 99 | * The number of arcs extending from this node. 100 | */ 101 | public function get numArcs():int 102 | { 103 | return _arcCount; 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/HashMap.as: -------------------------------------------------------------------------------- 1 | package de.polygonal.ds 2 | { 3 | import flash.utils.Dictionary; 4 | import de.polygonal.ds.Collection; 5 | 6 | public class HashMap implements Collection 7 | { 8 | private var _keyMap:Dictionary; 9 | private var _objMap:Dictionary; 10 | private var _size:int; 11 | 12 | /** 13 | * Initializes a hash map, which maps 14 | * keys to values. It cannot contain duplicate keys so 15 | * each key can map to at most one value. 16 | */ 17 | public function HashMap() 18 | { 19 | _keyMap = new Dictionary(true); 20 | _objMap = new Dictionary(true); 21 | _size = 0; 22 | } 23 | 24 | /** 25 | * Inserts a key/data couple into the table. 26 | * 27 | * @param key The key. 28 | * @param obj The data associated with the key. 29 | */ 30 | public function insert(key:*, obj:*):Boolean 31 | { 32 | if (_keyMap[key]) return false; 33 | ++_size; 34 | _objMap[obj] = key; 35 | _keyMap[key] = obj; 36 | return true; 37 | } 38 | 39 | /** 40 | * Finds the entry that is associated with the given key. 41 | * 42 | * @param key The key to search for. 43 | * @return The data associated with the key or null if no matching 44 | * entry was found. 45 | */ 46 | public function find(key:*):* 47 | { 48 | return _keyMap[key] || null; 49 | } 50 | 51 | /** 52 | * Finds the key that maps the given value. 53 | * 54 | * @param val The value which maps the sought-after key. 55 | * @return The key mapping the given value or null if no matching 56 | * key was found. 57 | */ 58 | public function findKey(val:*):* 59 | { 60 | return _objMap[val] || null; 61 | } 62 | 63 | /** 64 | * Removes an entry based on a given key. 65 | * 66 | * @param key The entry's key. 67 | * @return The data associated with the key or null if no matching 68 | * entry was found. 69 | */ 70 | public function remove(key:*):* 71 | { 72 | var obj:* = _keyMap[key]; 73 | 74 | if (obj) 75 | { 76 | --_size; 77 | delete _keyMap[key]; 78 | delete _objMap[obj]; 79 | return obj; 80 | } 81 | return null; 82 | } 83 | 84 | /** 85 | * Checks if a key maps the given value. 86 | * 87 | * @return True if value exists, otherwise false. 88 | */ 89 | public function contains(obj:*):Boolean 90 | { 91 | return _objMap[obj] ? true : false; 92 | } 93 | 94 | /** 95 | * Checks if a mapping exists for the given key. 96 | * 97 | * @return True if key exists, otherwise false. 98 | */ 99 | public function containsKey(key:*):Boolean 100 | { 101 | return _keyMap[key] ? true : false; 102 | } 103 | 104 | /** 105 | * Creates an interator for traversing the values. 106 | */ 107 | public function getIterator():Iterator 108 | { 109 | return new HashMapValueIterator(this); 110 | } 111 | 112 | /** 113 | * Creates an interator for traversing the keys. 114 | */ 115 | public function getKeyIterator():Iterator 116 | { 117 | return new HashMapKeyIterator(this); 118 | } 119 | 120 | /** 121 | * Clears all elements. 122 | */ 123 | public function clear():void 124 | { 125 | _keyMap = new Dictionary(true); 126 | _objMap = new Dictionary(true); 127 | _size = 0; 128 | } 129 | 130 | /** 131 | * The total number of items. 132 | */ 133 | public function get size():int 134 | { 135 | return _size; 136 | } 137 | 138 | /** 139 | * Checks if the map is empty. 140 | * 141 | * @return True if empty, otherwise false. 142 | */ 143 | public function isEmpty():Boolean 144 | { 145 | return _size == 0; 146 | } 147 | 148 | /** 149 | * Writes all values into an array. 150 | * 151 | * @return An array. 152 | */ 153 | public function toArray():Array 154 | { 155 | var a:Array = new Array(_size), j:int = 0; 156 | for each (var i:* in _keyMap) 157 | { 158 | a[j++] = i; 159 | } 160 | return a; 161 | } 162 | 163 | /** 164 | * Writes all keys into an array. 165 | * 166 | * @return An array. 167 | */ 168 | public function getKeySet():Array 169 | { 170 | var a:Array = new Array(_size), j:int = 0; 171 | for each (var i:* in _objMap) 172 | { 173 | a[j++] = i; 174 | } 175 | return a; 176 | } 177 | 178 | /** 179 | * Returns a string representing the current object. 180 | */ 181 | public function toString():String 182 | { 183 | return "[HashMap, size=" + size + "]"; 184 | } 185 | 186 | /** 187 | * Prints all elements (for debug/demo purposes only). 188 | */ 189 | public function dump():String 190 | { 191 | var s:String = "HashMap:\n"; 192 | for each (var i:* in _objMap) 193 | s += "[key: " + i + " val:" + _keyMap[i] + "]\n"; 194 | return s; 195 | } 196 | } 197 | } 198 | 199 | import de.polygonal.ds.Iterator; 200 | import de.polygonal.ds.HashMap; 201 | 202 | internal class HashMapValueIterator implements Iterator 203 | { 204 | private var _h:HashMap; 205 | private var _values:Array; 206 | private var _cursor:int; 207 | private var _size:int; 208 | 209 | public function HashMapValueIterator(h:HashMap) 210 | { 211 | _h = h; 212 | _values = h.toArray(); 213 | _cursor = 0; 214 | _size = _h.size; 215 | } 216 | 217 | public function get data():* 218 | { 219 | return _values[_cursor]; 220 | } 221 | 222 | public function set data(obj:*):void 223 | { 224 | var key:* = _h.findKey(_values[_cursor]); 225 | _h.remove(key); 226 | _h.insert(key, obj); 227 | } 228 | 229 | public function start():void 230 | { 231 | _cursor = 0; 232 | } 233 | 234 | public function hasNext():Boolean 235 | { 236 | return _cursor < _size; 237 | } 238 | 239 | public function next():* 240 | { 241 | return _values[_cursor++]; 242 | } 243 | } 244 | 245 | internal class HashMapKeyIterator implements Iterator 246 | { 247 | private var _h:HashMap; 248 | private var _keys:Array; 249 | private var _cursor:int; 250 | private var _size:int; 251 | 252 | public function HashMapKeyIterator(h:HashMap) 253 | { 254 | _h = h; 255 | _keys = h.getKeySet(); 256 | _cursor = 0; 257 | _size = _h.size; 258 | } 259 | 260 | public function get data():* 261 | { 262 | return _keys[_cursor]; 263 | } 264 | 265 | public function set data(obj:*):void 266 | { 267 | var key:* = _keys[_cursor]; 268 | var val:* = _h.find(key); 269 | _h.remove(key); 270 | _h.insert(obj, val); 271 | } 272 | 273 | public function start():void 274 | { 275 | _cursor = 0; 276 | } 277 | 278 | public function hasNext():Boolean 279 | { 280 | return _cursor < _size; 281 | } 282 | 283 | public function next():* 284 | { 285 | return _keys[_cursor++]; 286 | } 287 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/HashTable.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Iterator; 12 | 13 | /** 14 | * A hash table using linked overflow for resolving collisions. 15 | */ 16 | public class HashTable 17 | { 18 | /** 19 | * A simple function for hashing strings. 20 | */ 21 | public static function hashString(s:String):int 22 | { 23 | var hash:int = 0, i:int, k:int = s.length; 24 | for (i = 0; i < k; i++) 25 | hash += (i + 1) * s.charCodeAt(i); 26 | return hash; 27 | } 28 | 29 | /** 30 | * A simple function for hashing integers. 31 | */ 32 | public static function hashInt(i:int):int 33 | { 34 | return hashString(i.toString()); 35 | } 36 | 37 | private var _table:Array; 38 | private var _hash:Function; 39 | 40 | private var _size:int; 41 | private var _divisor:int; 42 | private var _count:int; 43 | 44 | /** 45 | * Initializes a hash table. 46 | * 47 | * @param size The size of the hash table. 48 | * @param hash A hashing function. 49 | */ 50 | public function HashTable(size:int, hash:Function = null) 51 | { 52 | _count = 0; 53 | 54 | _hash = (hash == null) ? function(key:int):int { return key } : hash; 55 | _table = new Array(_size = size); 56 | 57 | for (var i:int = 0; i < size; i++) 58 | _table[i] = []; 59 | 60 | _divisor = _size - 1; 61 | } 62 | 63 | /** 64 | * Inserts a key/data couple into the table. 65 | * 66 | * @param key The key. 67 | * @param obj The data associated with the key. 68 | */ 69 | public function insert(key:*, obj:*):void 70 | { 71 | _table[int(_hash(key) & _divisor)].push(new HashEntry(key, obj)); 72 | _count++; 73 | } 74 | 75 | /** 76 | * Finds the entry that is associated with the given key. 77 | * 78 | * @param key The key to search for. 79 | * @return The data associated with the key or null if no matching 80 | * entry was found. 81 | */ 82 | public function find(key:*):* 83 | { 84 | var list:Array = _table[int(_hash(key) & _divisor)]; 85 | var k:int = list.length, entry:HashEntry; 86 | for (var i:int = 0; i < k; i++) 87 | { 88 | entry = list[i]; 89 | if (entry.key === key) 90 | return entry.data; 91 | } 92 | return null; 93 | } 94 | 95 | /** 96 | * Removes an entry based on a given key. 97 | * 98 | * @param key The entry's key. 99 | * @return The data associated with the key or null if no matching 100 | * entry was found. 101 | */ 102 | public function remove(key:*):* 103 | { 104 | var list:Array = _table[int(_hash(key) & _divisor)]; 105 | var k:int = list.length; 106 | for (var i:int = 0; i < k; i++) 107 | { 108 | var entry:HashEntry = list[i]; 109 | if (entry.key === key) 110 | { 111 | list.splice(i, 1); 112 | return entry.data; 113 | } 114 | } 115 | return null; 116 | } 117 | 118 | /** 119 | * Checks if a given item exists. 120 | * 121 | * @return True if item exists, otherwise false. 122 | */ 123 | public function contains(obj:*):Boolean 124 | { 125 | var list:Array, k:int = size; 126 | for (var i:int = 0; i < k; i++) 127 | { 128 | list = _table[i]; 129 | var l:int = list.length; 130 | 131 | for (var j:int = 0; j < l; j++) 132 | if (list[j].data === obj) return true; 133 | } 134 | return false; 135 | } 136 | 137 | /** 138 | * Iterator not supported (yet). 139 | */ 140 | public function getIterator():Iterator 141 | { 142 | return new NullIterator(); 143 | } 144 | 145 | /** 146 | * Clears all elements. 147 | */ 148 | public function clear():void 149 | { 150 | _table = new Array(_size); 151 | _count = 0; 152 | } 153 | 154 | /** 155 | * The total number of items. 156 | */ 157 | public function get size():int 158 | { 159 | return _count; 160 | } 161 | 162 | /** 163 | * The maximum allowed size of the queue. 164 | */ 165 | public function get maxSize():int 166 | { 167 | return _size; 168 | } 169 | 170 | /** 171 | * Converts the structure into an array. 172 | * 173 | * @return An array. 174 | */ 175 | public function toArray():Array 176 | { 177 | var a:Array = [], list:Array, k:int = size; 178 | for (var i:int = 0; i < k; i++) 179 | { 180 | list = _table[i]; 181 | var l:int = list.length; 182 | 183 | for (var j:int = 0; j < l; j++) 184 | a.push(list[j]); 185 | } 186 | return a; 187 | } 188 | 189 | /** 190 | * Returns a string representing the current object. 191 | */ 192 | public function toString():String 193 | { 194 | return "[HashTable, size=" + size + "]"; 195 | } 196 | 197 | public function print():String 198 | { 199 | var s:String = "HashTable:\n"; 200 | for (var i:int = 0; i < _size; i++) 201 | { 202 | if (_table[i]) 203 | s += "[" + i + "]" + "\n" + _table[i]; 204 | } 205 | return s; 206 | } 207 | } 208 | } 209 | 210 | /** 211 | * Simple container class for storing a key/data couple. 212 | */ 213 | internal class HashEntry 214 | { 215 | public var key:int; 216 | 217 | public var data:*; 218 | 219 | public function HashEntry(key:int, data:*) 220 | { 221 | this.key = key; 222 | this.data = data; 223 | } 224 | } 225 | 226 | 227 | -------------------------------------------------------------------------------- /src/de/polygonal/ds/Heap.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Collection; 12 | import de.polygonal.ds.Iterator; 13 | 14 | /** 15 | * A heap. 16 | * 17 | *A heap is a special kind of binary tree in which every node is 18 | * greater than all of its children. The implementation is based on an arrayed binary tree. 19 | * It can be used as an efficient priority queue.
20 | * @see PriorityQueue 21 | */ 22 | public class Heap implements Collection 23 | { 24 | public var _heap:Array; 25 | 26 | private var _size:int; 27 | private var _count:int; 28 | private var _compare:Function; 29 | 30 | /** 31 | * Initializes a new heap. 32 | */ 33 | public function Heap(size:int, compare:Function = null) 34 | { 35 | _heap = new Array(_size = size + 1); 36 | _count = 0; 37 | 38 | if (compare == null) 39 | { 40 | _compare = function(a:int, b:int):int 41 | { 42 | return a - b; 43 | } 44 | } 45 | else 46 | _compare = compare; 47 | } 48 | 49 | /** 50 | * The heap's front item. 51 | */ 52 | public function get front():* 53 | { 54 | return _heap[1]; 55 | } 56 | 57 | /** 58 | * Enqueues some data. 59 | * 60 | * @param obj The data. 61 | */ 62 | public function enqueue(obj:*):void 63 | { 64 | _heap[++_count] = obj; 65 | walkUp(_count); 66 | } 67 | 68 | /** 69 | * Dequeues the front item. 70 | */ 71 | public function dequeue():void 72 | { 73 | if (_count >= 1) 74 | { 75 | _heap[1] = _heap[_count]; 76 | delete _heap[_count]; 77 | 78 | walkDown(1); 79 | _count--; 80 | } 81 | } 82 | 83 | /** 84 | * Checks if a given item exists. 85 | * 86 | * @return True if the item is found, otherwise false. 87 | */ 88 | public function contains(obj:*):Boolean 89 | { 90 | for (var i:int = 1; i <= _count; i++) 91 | { 92 | if (_heap[i] === obj) 93 | return true; 94 | } 95 | return false; 96 | } 97 | 98 | /** 99 | * Clears all items. 100 | */ 101 | public function clear():void 102 | { 103 | _heap = new Array(_size); 104 | _count = 0; 105 | } 106 | 107 | /** 108 | * Returns an iterator object pointing to the front 109 | * item. 110 | * 111 | * @return An iterator object. 112 | */ 113 | public function getIterator():Iterator 114 | { 115 | return new HeapIterator(this); 116 | } 117 | 118 | /** 119 | * The total number of items in the heap. 120 | */ 121 | public function get size():int 122 | { 123 | return _count; 124 | } 125 | 126 | /** 127 | * Checks if the heap is empty. 128 | */ 129 | public function isEmpty():Boolean 130 | { 131 | return false; 132 | } 133 | 134 | /** 135 | * The maximum allowed size of the queue. 136 | */ 137 | public function get maxSize():int 138 | { 139 | return _size; 140 | } 141 | 142 | /** 143 | * Converts the heap into an array. 144 | * 145 | * @return An array containing all heap values. 146 | */ 147 | public function toArray():Array 148 | { 149 | return _heap.slice(1, _count); 150 | } 151 | 152 | private function walkUp(index:int):void 153 | { 154 | var parent:int = index >> 1; 155 | var tmp:* = _heap[index]; 156 | while (parent > 0) 157 | { 158 | if (_compare(tmp, _heap[parent]) > 0) 159 | { 160 | _heap[index] = _heap[parent]; 161 | index = parent; 162 | parent >>= 1; 163 | } 164 | else break; 165 | } 166 | _heap[index] = tmp; 167 | } 168 | 169 | private function walkDown(index:int):void 170 | { 171 | var child:int = index << 1; 172 | 173 | var tmp:* = _heap[index], c:*; 174 | 175 | while (child < _count) 176 | { 177 | if (child < _count - 1) 178 | { 179 | if (_compare(_heap[child], _heap[int(child + 1)]) < 0) 180 | child++; 181 | } 182 | if (_compare(tmp, _heap[child]) < 0) 183 | { 184 | _heap[index] = _heap[child]; 185 | index = child; 186 | child <<= 1; 187 | } 188 | else break; 189 | } 190 | _heap[index] = tmp; 191 | } 192 | } 193 | } 194 | 195 | import de.polygonal.ds.Iterator; 196 | import de.polygonal.ds.Heap; 197 | 198 | internal class HeapIterator implements Iterator 199 | { 200 | private var _values:Array; 201 | private var _length:int; 202 | private var _cursor:int; 203 | 204 | public function HeapIterator(heap:Heap) 205 | { 206 | _values = heap.toArray(); 207 | _length = _values.length; 208 | _cursor = 0; 209 | } 210 | 211 | public function get data():* 212 | { 213 | return _values[_cursor]; 214 | } 215 | 216 | public function set data(obj:*):void 217 | { 218 | _values[_cursor] = obj; 219 | } 220 | 221 | public function start():void 222 | { 223 | _cursor = 0; 224 | } 225 | 226 | public function hasNext():Boolean 227 | { 228 | return _cursor < _length; 229 | } 230 | 231 | public function next():* 232 | { 233 | return _values[_cursor++]; 234 | } 235 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/Iterator.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | /** 12 | * A 'java-style' iterator interface. 13 | */ 14 | public interface Iterator 15 | { 16 | /** 17 | * Retrieves the current item and moves 18 | * the iterator to the next item in the sequence. 19 | */ 20 | function next():* 21 | 22 | /** 23 | * Checks if the next item exists. 24 | * 25 | * @return True if a next item exists, otherwise false. 26 | */ 27 | function hasNext():Boolean 28 | 29 | /** 30 | * Moves the iterator to the first item 31 | * in the sequence. 32 | */ 33 | function start():void 34 | 35 | /** 36 | * Grants access to the current item being 37 | * referenced by the iterator. This provides 38 | * a quick way to read or write the current data. 39 | */ 40 | function get data():* 41 | function set data(obj:*):void 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/de/polygonal/ds/LinkedList.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | /** 12 | * A marker interface for the singly linked and doubly 13 | * linked list class. 14 | */ 15 | public interface LinkedList 16 | { 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/de/polygonal/ds/LinkedQueue.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.SLinkedList; 12 | 13 | /** 14 | * A linked queue. 15 | * 16 | *A queue is a FIFO structure (First In, First Out).
17 | */ 18 | public class LinkedQueue 19 | { 20 | private var _list:SLinkedList; 21 | 22 | /** 23 | * Initializes an empty linked queue. 24 | * You can pass an existing singly linked list 25 | * to provide queue-like access. 26 | * 27 | * @param list An existing list to use as a queue. 28 | */ 29 | public function LinkedQueue(list:SLinkedList = null) 30 | { 31 | if (list == null) 32 | _list = new SLinkedList(); 33 | else 34 | _list = list; 35 | } 36 | 37 | /** 38 | * The total number of items in the queue. 39 | */ 40 | public function get size():int 41 | { 42 | return _list.size; 43 | } 44 | 45 | /** 46 | * Indicates the front item. 47 | * 48 | * @return The front item. 49 | */ 50 | public function peek():* 51 | { 52 | if (_list.size > 0) 53 | return _list.head.data; 54 | return null; 55 | } 56 | 57 | /** 58 | * Clears all elements. 59 | */ 60 | public function clear():void 61 | { 62 | _list.clear(); 63 | } 64 | 65 | /** 66 | * Enqueues some data. 67 | * 68 | * @param obj The data. 69 | */ 70 | public function enqueue(obj:*):void 71 | { 72 | _list.append(obj); 73 | } 74 | 75 | /** 76 | * Dequeues the front item. 77 | */ 78 | /** 79 | * Dequeues and returns the front item. 80 | * 81 | * @return The front item or null if the queue is empty. 82 | */ 83 | public function dequeue():* 84 | { 85 | if (_list.size > 0) 86 | { 87 | var front:* = _list.head.data; 88 | _list.removeHead(); 89 | return front; 90 | } 91 | return null; 92 | } 93 | 94 | /** 95 | * Returns a string representing the current object. 96 | */ 97 | public function toString():String 98 | { 99 | return "[LinkedQueue > " + _list + "]"; 100 | } 101 | 102 | /** 103 | * Prints out all elements in the queue (for debug/demo purposes). 104 | */ 105 | public function dump():String 106 | { 107 | return "LinkedQueue:\n" + _list.dump(); 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/LinkedStack.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.DLinkedList; 12 | 13 | /** 14 | * A linked stack. 15 | *A stack is a LIFO structure (Last In, First Out)
. 16 | */ 17 | public class LinkedStack 18 | { 19 | private var _list:DLinkedList; 20 | 21 | /** 22 | * Initializes a linked stack. 23 | * You can pass an existing doubly linked list 24 | * to provide stack-like access. 25 | * 26 | * @param list An existing list to use as a stack. 27 | */ 28 | public function LinkedStack(list:DLinkedList = null) 29 | { 30 | if (list == null) 31 | _list = new DLinkedList(); 32 | else 33 | _list = list; 34 | } 35 | 36 | /** 37 | * The total number of items in the stack. 38 | */ 39 | public function get size():int 40 | { 41 | return _list.size; 42 | } 43 | 44 | /** 45 | * Indicates the top item. 46 | * 47 | * @return The top item. 48 | */ 49 | public function peek():* 50 | { 51 | if (_list.size > 0) 52 | return _list.tail.data; 53 | else 54 | return null; 55 | } 56 | 57 | /** 58 | * Pushes data onto the stack. 59 | * 60 | * @param obj The data to insert. 61 | */ 62 | public function push(obj:*):void 63 | { 64 | _list.append(obj); 65 | } 66 | 67 | /** 68 | * Pops data from the stack. 69 | * 70 | * @return The top item. 71 | */ 72 | public function pop():void 73 | { 74 | _list.removeTail(); 75 | } 76 | 77 | /** 78 | * Returns a string representing the current object. 79 | */ 80 | public function toString():String 81 | { 82 | return "[LinkedStack > " + _list + "]"; 83 | } 84 | 85 | /** 86 | * Prints out all elements in the stack (for debug/demo purposes). 87 | */ 88 | public function dump():String 89 | { 90 | return "LinkedStack:\n" + _list.dump(); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/NullIterator.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Iterator; 12 | 13 | /** 14 | * An do-nothing iterator for structures that don't support iterators. 15 | */ 16 | public class NullIterator implements Iterator 17 | { 18 | public function start():void 19 | { 20 | } 21 | 22 | public function next():* 23 | { 24 | return null; 25 | } 26 | 27 | public function hasNext():Boolean 28 | { 29 | return false; 30 | } 31 | 32 | public function get data():* 33 | { 34 | return null; 35 | } 36 | 37 | public function set data(obj:*):void 38 | { 39 | } 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/de/polygonal/ds/Prioritizable.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | /** 12 | * All objects you want to insert into a PriorityQueue have to extend this class. 13 | * 14 | *I could have defined this as an interface, but this would 15 | * force me to write functions to just get or set the priority value.
16 | */ 17 | public class Prioritizable 18 | { 19 | public var priority:int; 20 | 21 | public function Prioritizable() 22 | { 23 | priority = -1; 24 | } 25 | 26 | public function toString():String 27 | { 28 | return "[Prioritizable, priority=" + priority + "]"; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/PriorityQueue.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import flash.utils.Dictionary; 12 | import de.polygonal.ds.Collection; 13 | 14 | /** 15 | * A priority queue. 16 | * 17 | *The priority queue is based on the heap structure and 18 | * manages prioritized data.
19 | */ 20 | public class PriorityQueue implements Collection 21 | { 22 | private var _heap:Array; 23 | private var _size:int; 24 | private var _count:int; 25 | private var _posLookup:Dictionary; 26 | 27 | /** 28 | * Initializes a priority queue with a given size. 29 | * 30 | * @param size The size of the priority queue. 31 | */ 32 | public function PriorityQueue(size:int) 33 | { 34 | _heap = new Array(_size = size + 1); 35 | _posLookup = new Dictionary(true); 36 | _count = 0; 37 | } 38 | 39 | /** 40 | * The priority queue's front item. 41 | */ 42 | public function get front():Prioritizable 43 | { 44 | return _heap[1]; 45 | } 46 | 47 | /** 48 | * Enqueues a prioritized object. 49 | * 50 | * @param obj The prioritized data. 51 | */ 52 | public function enqueue(obj:Prioritizable):void 53 | { 54 | _count++; 55 | _heap[_count] = obj; 56 | _posLookup[obj] = _count; 57 | walkUp(_count); 58 | } 59 | 60 | /** 61 | * Dequeues the front item, which is the item 62 | * with the highest priority. 63 | */ 64 | public function dequeue():void 65 | { 66 | if (_count >= 1) 67 | { 68 | delete _posLookup[_heap[1]]; 69 | 70 | _heap[1] = _heap[_count]; 71 | walkDown(1); 72 | delete _heap[_count]; 73 | _count--; 74 | } 75 | } 76 | 77 | /** 78 | * Reprioritizes an item. 79 | * 80 | * @param obj The object whose priority is changed. 81 | * @param newPriority The new priority. 82 | * @return True if the repriorization succeeded, otherwise false. 83 | */ 84 | public function reprioritize(obj:Prioritizable, newPriority:int):Boolean 85 | { 86 | if (!_posLookup[obj]) return false; 87 | 88 | var oldPriority:int = obj.priority; 89 | 90 | //App.tr("old priority=", obj.priority); 91 | 92 | obj.priority = newPriority; 93 | 94 | //App.tr("new priority=", obj.priority); 95 | 96 | var pos:int = _posLookup[obj]; 97 | 98 | //App.tr("current pos=", pos); 99 | 100 | //App.tr("now ", newPriority > p ? "Walkup" : "WalkDown"); 101 | 102 | newPriority > oldPriority ? walkUp(pos) : walkDown(pos); 103 | 104 | return true; 105 | } 106 | 107 | /** 108 | * Removes an item. 109 | * 110 | * @param obj The object to remove. 111 | * @return True if removal succeeded, otherwise false. 112 | */ 113 | public function remove(obj:Prioritizable):Boolean 114 | { 115 | if (!_posLookup[obj]) return false; 116 | 117 | var pos:int = _posLookup[obj]; 118 | delete _posLookup[obj]; 119 | 120 | _heap[pos] = _heap[_count]; 121 | delete _heap[_count]; 122 | 123 | walkDown(pos); 124 | _count--; 125 | 126 | return true; 127 | } 128 | 129 | /** 130 | * Checks if a given item exists. 131 | * 132 | * @return True if the item is found, otherwise false. 133 | */ 134 | public function contains(obj:*):Boolean 135 | { 136 | for (var i:int = 1; i <= _count; i++) 137 | { 138 | if (_heap[i] === obj) 139 | return true; 140 | } 141 | return false; 142 | } 143 | 144 | /** 145 | * Clears all items. 146 | */ 147 | public function clear():void 148 | { 149 | _heap = new Array(_size); 150 | _posLookup = new Dictionary(true); 151 | _count = 0; 152 | } 153 | 154 | /** 155 | * Returns an iterator object pointing to the front 156 | * item. 157 | * 158 | * @return An iterator object. 159 | */ 160 | public function getIterator():Iterator 161 | { 162 | return new PriorityQueueIterator(this); 163 | } 164 | 165 | /** 166 | * The total number of items in the priority queue. 167 | */ 168 | public function get size():int 169 | { 170 | return _count; 171 | } 172 | 173 | /** 174 | * Checks if the priority queue is empty. 175 | */ 176 | public function isEmpty():Boolean 177 | { 178 | return false; 179 | } 180 | 181 | /** 182 | * The maximum allowed size of the queue. 183 | */ 184 | public function get maxSize():int 185 | { 186 | return _size; 187 | } 188 | 189 | /** 190 | * Converts the priority queue into an array. 191 | * 192 | * @return An array containing all values. 193 | */ 194 | public function toArray():Array 195 | { 196 | return _heap.slice(1, _count); 197 | } 198 | 199 | private function walkUp(index:int):void 200 | { 201 | var parent:int = index >> 1; 202 | var parentObj:Prioritizable; 203 | 204 | var tmp:Prioritizable = _heap[index]; 205 | var p:int = tmp.priority; 206 | 207 | while (parent > 0) 208 | { 209 | parentObj = _heap[parent]; 210 | 211 | if (p - parentObj.priority > 0) 212 | { 213 | _heap[index] = parentObj; 214 | _posLookup[parentObj] = index; 215 | 216 | index = parent; 217 | parent >>= 1; 218 | } 219 | else break; 220 | } 221 | 222 | _heap[index] = tmp; 223 | _posLookup[tmp] = index; 224 | } 225 | 226 | private function walkDown(index:int):void 227 | { 228 | var child:int = index << 1; 229 | var childObj:Prioritizable; 230 | 231 | var tmp:Prioritizable = _heap[index]; 232 | var p:int = tmp.priority; 233 | 234 | while (child < _count) 235 | { 236 | if (child < _count - 1) 237 | { 238 | if (_heap[child].priority - _heap[int(child + 1)].priority < 0) 239 | child++; 240 | } 241 | 242 | childObj = _heap[child]; 243 | 244 | if (p - childObj.priority < 0) 245 | { 246 | _heap[index] = childObj; 247 | _posLookup[childObj] = child; 248 | 249 | index = child; 250 | child <<= 1; 251 | } 252 | else break; 253 | } 254 | _heap[index] = tmp; 255 | _posLookup[tmp] = index; 256 | } 257 | } 258 | } 259 | 260 | import de.polygonal.ds.Iterator; 261 | import de.polygonal.ds.PriorityQueue; 262 | 263 | internal class PriorityQueueIterator implements Iterator 264 | { 265 | private var _values:Array; 266 | private var _length:int; 267 | private var _cursor:int; 268 | 269 | public function PriorityQueueIterator(pq:PriorityQueue) 270 | { 271 | _values = pq.toArray(); 272 | _length = _values.length; 273 | _cursor = 0; 274 | } 275 | 276 | public function get data():* 277 | { 278 | return _values[_cursor]; 279 | } 280 | 281 | public function set data(obj:*):void 282 | { 283 | _values[_cursor] = obj; 284 | } 285 | 286 | public function start():void 287 | { 288 | _cursor = 0; 289 | } 290 | 291 | public function hasNext():Boolean 292 | { 293 | return _cursor < _length; 294 | } 295 | 296 | public function next():* 297 | { 298 | return _values[_cursor++]; 299 | } 300 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/SLinkedList.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Collection; 12 | import de.polygonal.ds.Iterator; 13 | import de.polygonal.ds.SListNode; 14 | import de.polygonal.ds.SListIterator; 15 | 16 | /** 17 | * A singly linked list. 18 | */ 19 | public class SLinkedList implements Collection 20 | { 21 | private var _count:int; 22 | 23 | /** 24 | * The head node being referenced. 25 | */ 26 | public var head:SListNode; 27 | 28 | /** 29 | * The tail node being referenced. 30 | */ 31 | public var tail:SListNode; 32 | 33 | /** 34 | * Initializes an empty list. 35 | */ 36 | public function SLinkedList() 37 | { 38 | head = tail = null; 39 | _count = 0; 40 | } 41 | 42 | /** 43 | * Appends an item to the list. 44 | * 45 | * @param obj The data. 46 | * @return A singly linked list node wrapping the data. 47 | */ 48 | public function append(obj:*):SListNode 49 | { 50 | var node:SListNode = new SListNode(obj); 51 | if (head) 52 | { 53 | tail.next = node; 54 | tail = node; 55 | } 56 | else 57 | head = tail = node; 58 | 59 | _count++; 60 | return node; 61 | } 62 | 63 | /** 64 | * Prepends an item to the list. 65 | * 66 | * @param obj The data. 67 | * @return A singly linked list node wrapping the data. 68 | */ 69 | public function prepend(obj:*):SListNode 70 | { 71 | var node:SListNode = new SListNode(obj); 72 | 73 | if (head) 74 | { 75 | node.next = head; 76 | head = node; 77 | } 78 | else 79 | head = tail = node; 80 | 81 | _count++; 82 | return node; 83 | } 84 | 85 | /** 86 | * Inserts data after a given iterator or appends it 87 | * if the iterator is invalid. 88 | * 89 | * @param itr A singly linked list iterator. 90 | * @param obj The data. 91 | * @return A singly linked list node wrapping the data. 92 | */ 93 | public function insertAfter(itr:SListIterator, obj:*):SListNode 94 | { 95 | if (itr.list != this) return null; 96 | if (itr.node) 97 | { 98 | var node:SListNode = new SListNode(obj); 99 | itr.node.insertAfter(node); 100 | if (itr.node == tail) 101 | tail = itr.node.next; 102 | 103 | _count++; 104 | return node; 105 | } 106 | else 107 | return append(obj); 108 | } 109 | 110 | /** 111 | * Removes the node the iterator is pointing 112 | * to and move the iterator to the next node. 113 | * 114 | * @return True if the removal succeeded, otherwise false. 115 | */ 116 | public function remove(itr:SListIterator):Boolean 117 | { 118 | if (itr.list != this || !itr.node) return false; 119 | 120 | var node:SListNode = head; 121 | if (itr.node == head) 122 | { 123 | itr.forth(); 124 | removeHead(); 125 | } 126 | else 127 | { 128 | while (node.next != itr.node) node = node.next; 129 | itr.forth(); 130 | if (node.next == tail) tail = node; 131 | node.next = itr.node; 132 | } 133 | _count--; 134 | return true; 135 | } 136 | 137 | /** 138 | * Removes the head of the list. 139 | */ 140 | public function removeHead():void 141 | { 142 | if (!head) return; 143 | 144 | if (head == tail) 145 | head = tail = null; 146 | else 147 | { 148 | var node:SListNode = head; 149 | 150 | head = head.next; 151 | node.next = null; 152 | if (head == null) tail = null; 153 | } 154 | _count--; 155 | } 156 | 157 | /** 158 | * Removes the tail of the list. 159 | */ 160 | public function removeTail():void 161 | { 162 | if (!tail) return; 163 | 164 | if (head == tail) 165 | head = tail = null; 166 | else 167 | { 168 | var node:SListNode = head; 169 | while (node.next != tail) 170 | node = node.next; 171 | 172 | tail = node; 173 | node.next = null; 174 | } 175 | _count--; 176 | } 177 | 178 | /** 179 | * Checks if a given item exists. 180 | * 181 | * @return True if the item is found, otherwise false. 182 | */ 183 | public function contains(obj:*):Boolean 184 | { 185 | var node:SListNode = head; 186 | while (node) 187 | { 188 | if (node.data == obj) return true; 189 | node = node.next; 190 | } 191 | return false; 192 | } 193 | 194 | /** 195 | * Clears the list by unlinking all nodes 196 | * from it. This is important to unlock 197 | * the nodes for the garbage collector. 198 | */ 199 | public function clear():void 200 | { 201 | var node:SListNode = head; 202 | head = null; 203 | 204 | var next:SListNode; 205 | while (node) 206 | { 207 | next = node.next; 208 | node.next = null; 209 | node = next; 210 | } 211 | _count = 0; 212 | } 213 | 214 | /** 215 | * Creates an iterator pointing 216 | * to the first node in the list. 217 | * 218 | * @returns An iterator object. 219 | */ 220 | public function getIterator():Iterator 221 | { 222 | return new SListIterator(this, head); 223 | } 224 | 225 | /** 226 | * Creates a list iterator pointing 227 | * to the first node in the list. 228 | * 229 | * @returns A SListIterator object. 230 | */ 231 | public function getListIterator():SListIterator 232 | { 233 | return new SListIterator(this, head); 234 | } 235 | 236 | /** 237 | * The total number of nodes in the list. 238 | */ 239 | public function get size():int 240 | { 241 | return _count; 242 | } 243 | 244 | /** 245 | * Checks if the list is empty. 246 | */ 247 | public function isEmpty():Boolean 248 | { 249 | return _count == 0; 250 | } 251 | 252 | /** 253 | * Converts the linked list into an array. 254 | * 255 | * @return An array. 256 | */ 257 | public function toArray():Array 258 | { 259 | var a:Array = []; 260 | var node:SListNode = head; 261 | while (node) 262 | { 263 | a.push(node.data); 264 | node = node.next; 265 | } 266 | return a; 267 | } 268 | 269 | /** 270 | * Returns a string representing the current object. 271 | */ 272 | public function toString():String 273 | { 274 | return "[SlinkedList, size=" + size + "]"; 275 | } 276 | 277 | /** 278 | * Prints out all elements in the list (for debug/demo purposes). 279 | */ 280 | public function dump():String 281 | { 282 | if (!head) 283 | return "SLinkedList: (empty)"; 284 | 285 | var s:String = "SLinkedList: (has " + _count + " node" + (_count == 1 ? ")" : "s") + "\n|< Head\n"; 286 | 287 | var itr:SListIterator = getListIterator(); 288 | for (; itr.valid(); itr.forth()) 289 | s += "\t" + itr.data + "\n"; 290 | 291 | s += "Tail >|"; 292 | 293 | return s; 294 | } 295 | } 296 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/SListIterator.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.SListNode; 12 | import de.polygonal.ds.SLinkedList; 13 | 14 | /** 15 | * A singly linked list iterator. 16 | */ 17 | public class SListIterator implements Iterator 18 | { 19 | /** 20 | * The node the iterator is pointing. 21 | */ 22 | public var node:SListNode; 23 | 24 | /** 25 | * The list of the iterator is referenced. 26 | */ 27 | public var list:SLinkedList; 28 | 29 | /** 30 | * Initializes a new SListIterator instance pointing to a given node. 31 | * Usually created by invoking SLinkedList.getIterator(). 32 | * 33 | * @param list The linked list the iterator should use. 34 | * @param node The iterator's initial node. 35 | */ 36 | public function SListIterator(list:SLinkedList = null, node:SListNode = null) 37 | { 38 | this.list = list; 39 | this.node = node; 40 | } 41 | 42 | /** 43 | * Returns the current node's data while 44 | * moving the iterator forward by one position. 45 | */ 46 | public function next():* 47 | { 48 | if (hasNext()) 49 | { 50 | var obj:* = node.data; 51 | node = node.next; 52 | return obj; 53 | } 54 | return null 55 | } 56 | 57 | /** 58 | * Checks if a next node exists. 59 | */ 60 | public function hasNext():Boolean 61 | { 62 | return Boolean(node); 63 | } 64 | 65 | /** 66 | * Read/writes the current node's data. 67 | * 68 | * @return The data. 69 | */ 70 | public function get data():* 71 | { 72 | if (node) return node.data; 73 | return null; 74 | } 75 | 76 | public function set data(obj:*):void 77 | { 78 | node.data = obj; 79 | } 80 | 81 | 82 | /** 83 | * Moves the iterator to the start of the list. 84 | */ 85 | public function start():void 86 | { 87 | if (list) node = list.head; 88 | } 89 | 90 | /** 91 | * Moves the iterator to the end of the list. 92 | */ 93 | public function end():void 94 | { 95 | if (list) node = list.tail; 96 | } 97 | 98 | /** 99 | * Moves the iterator to the next node. 100 | */ 101 | public function forth():void 102 | { 103 | if (node) node = node.next; 104 | } 105 | 106 | /** 107 | * Checks if the current referenced node is valid. 108 | * 109 | * @return True if the node exists, otherwise false. 110 | */ 111 | public function valid():Boolean 112 | { 113 | return Boolean(node); 114 | } 115 | 116 | /** 117 | * Removes the node the iterator is 118 | * pointing to. 119 | */ 120 | public function remove():void 121 | { 122 | list.remove(this); 123 | } 124 | 125 | /** 126 | * Returns a string representing the current object. 127 | */ 128 | public function toString():String 129 | { 130 | return "{SListIterator: data=" + node.data + "}"; 131 | } 132 | } 133 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/SListNode.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | /** 12 | * A singly linked list node. 13 | * 14 | * The node acts as a data container and also 15 | * holds a reference to next node in the list. 16 | */ 17 | public class SListNode 18 | { 19 | /** 20 | * The node's data. 21 | */ 22 | public var data:*; 23 | 24 | /** 25 | * The next node in the list being referenced. 26 | */ 27 | public var next:SListNode; 28 | 29 | /** 30 | * Initializes a new node that stores 31 | * the given item. 32 | * 33 | * @param obj The data to store in the node. 34 | */ 35 | public function SListNode(obj:*) 36 | { 37 | data = obj; 38 | next = null; 39 | } 40 | 41 | /** 42 | * A helper function used solely by the SLinkedList class 43 | * for node insertion. 44 | * 45 | * @param node The node after which this node is inserted. 46 | */ 47 | public function insertAfter(node:SListNode):void 48 | { 49 | node.next = next; 50 | next = node; 51 | } 52 | 53 | /** 54 | * Returns a string representing the current object. 55 | */ 56 | public function toString():String 57 | { 58 | return "[SListNode, data=" + data + "]"; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/de/polygonal/ds/TreeNode.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Michael Baczynski 2007 3 | * http://lab.polygonal.de/ds/ 4 | * 5 | * This software is distributed under licence. Use of this software 6 | * implies agreement with all terms and conditions of the accompanying 7 | * software licence. 8 | */ 9 | package de.polygonal.ds 10 | { 11 | import de.polygonal.ds.Iterator; 12 | import de.polygonal.ds.Collection; 13 | 14 | import de.polygonal.ds.TreeNode; 15 | import de.polygonal.ds.TreeIterator; 16 | 17 | import de.polygonal.ds.DListNode; 18 | import de.polygonal.ds.DLinkedList; 19 | 20 | /** 21 | * A tree node. 22 | * 23 | *A tree only consists of TreeNode objects - there is no class that manages a tree structure. 24 | * Every tree node has a linked list of child nodes and a pointer to its parent node.
25 | */ 26 | public class TreeNode implements Collection 27 | { 28 | /** 29 | * The parent node being referenced. 30 | */ 31 | public var parent:TreeNode; 32 | 33 | /** 34 | * A list of child nodes being referenced. 35 | */ 36 | public var children:DLinkedList; 37 | 38 | /** 39 | * The data being referened. 40 | */ 41 | public var data:*; 42 | 43 | /** 44 | * Initializes a tree node. 45 | * 46 | * @param obj The data to store. 47 | * @param parent The node's parent node. 48 | */ 49 | public function TreeNode(obj:* = null, parent:TreeNode = null) 50 | { 51 | data = obj; 52 | children = new DLinkedList(); 53 | 54 | if (parent) 55 | { 56 | this.parent = parent; 57 | parent.children.append(this); 58 | } 59 | } 60 | 61 | /** 62 | * Counts the total number of tree nodes 63 | * starting from the current tree node. 64 | */ 65 | public function get size():int 66 | { 67 | var c:int = 1; 68 | var node:DListNode = children.head; 69 | while (node) 70 | { 71 | c += node.data.size; 72 | node = node.next; 73 | } 74 | return c; 75 | } 76 | 77 | /** 78 | * Checks is the tree node is empty (has no children). 79 | */ 80 | public function isEmpty():Boolean 81 | { 82 | return children.size == 0; 83 | } 84 | 85 | /** 86 | * Computes the depth of the tree, 87 | * starting from this node. 88 | */ 89 | public function get depth():int 90 | { 91 | if (!parent) return 0; 92 | 93 | var node:TreeNode = this, c:int = 0; 94 | while (node.parent) 95 | { 96 | c++; 97 | node = node.parent; 98 | } 99 | return c; 100 | } 101 | 102 | /** 103 | * The total number of childrens. 104 | */ 105 | public function get numChildrens():int 106 | { 107 | return children.size; 108 | } 109 | 110 | /** 111 | * The total number of siblings. 112 | */ 113 | public function get numSiblings():int 114 | { 115 | if (parent) 116 | return parent.children.size; 117 | return 0; 118 | } 119 | 120 | /** 121 | * Recursively removes every child node from this node. 122 | * This is important for unlocking the nodes for 123 | * the garbage collector. 124 | */ 125 | public function destroy():void 126 | { 127 | while (children.head) 128 | { 129 | var node:TreeNode = children.head.data; 130 | children.removeHead(); 131 | node.destroy(); 132 | } 133 | } 134 | 135 | /** 136 | * Checks if a given item exists. 137 | * 138 | * @return True if the item is found, otherwise false. 139 | */ 140 | public function contains(obj:*):Boolean 141 | { 142 | var found:Boolean = false; 143 | TreeIterator.preorder(this, function(node:TreeNode):void 144 | { 145 | if (obj == node.data) 146 | found = true; 147 | }); 148 | return found; 149 | } 150 | 151 | /** 152 | * Clears the tree by unlinking 153 | * all child nodes from the node on which 154 | * the method is called. 155 | */ 156 | public function clear():void 157 | { 158 | destroy(); 159 | } 160 | 161 | /** 162 | * Creates an iterator object pointing to the 163 | * node the method is called on. 164 | */ 165 | public function getIterator():Iterator 166 | { 167 | return new TreeIterator(this); 168 | } 169 | 170 | /** 171 | * Creates a tree iterator object pointing 172 | * at the node on which the method is called. 173 | * 174 | * @returns A TreeIterator object. 175 | */ 176 | public function getTreeIterator():TreeIterator 177 | { 178 | return new TreeIterator(this); 179 | } 180 | 181 | /** 182 | * Converts the tree into an array. 183 | * 184 | * @return An array. 185 | */ 186 | public function toArray():Array 187 | { 188 | var a:Array = []; 189 | TreeIterator.preorder(this, function(node:TreeNode):void 190 | { 191 | a.push(node.data); 192 | }); 193 | return a; 194 | } 195 | 196 | 197 | 198 | /** 199 | * Returns a string representing the current object. 200 | */ 201 | public function toString():String 202 | { 203 | var s:String = "[TreeNode > " + (parent == null ? "(root)" : ""); 204 | 205 | if (children.size == 0) 206 | s += "(leaf)"; 207 | else 208 | s += " has " + children.size + " child node" + (size > 1 || size == 0 ? "s" : ""); 209 | 210 | s += ", data=" + data + "]"; 211 | 212 | return s; 213 | } 214 | 215 | /** 216 | * Prints out all children recursively starting from the current node. 217 | */ 218 | public function dump():String 219 | { 220 | var s:String = ""; 221 | TreeIterator.preorder(this, function(node:TreeNode):void 222 | { 223 | var d:int = node.depth; 224 | 225 | for (var i:int = 0; i < d; i++) 226 | { 227 | if (i == d - 1) 228 | s += "+---"; 229 | else 230 | s += "| "; 231 | } 232 | s += node + "\n"; 233 | }); 234 | return s; 235 | } 236 | } 237 | } -------------------------------------------------------------------------------- /src/drumkitclass.as: -------------------------------------------------------------------------------- 1 | package { 2 | import flash.display.*; 3 | import flash.geom.*; 4 | import flash.events.*; 5 | import flash.net.*; 6 | import org.si.sion.SiONVoice; 7 | 8 | public class drumkitclass { 9 | public function drumkitclass():void { 10 | size = 0; 11 | } 12 | 13 | public function updatefilter(cutoff:int, resonance:int):void { 14 | for (var i:int = 0; i < size; i++) { 15 | if(voicelist[i].channelParam.cutoff != cutoff || voicelist[i].channelParam.resonance != resonance){ 16 | voicelist[i].setFilterEnvelop(0, cutoff, resonance); 17 | } 18 | } 19 | } 20 | 21 | public function updatevolume(volume:int):void { 22 | for (var i:int = 0; i < size; i++) { 23 | if(voicelist[i].velocity!=volume){ 24 | voicelist[i].updateVolumes = true; 25 | voicelist[i].velocity = volume; 26 | } 27 | } 28 | } 29 | 30 | public var voicelist:Vector.bytes = [ n/(128p)%128 | 0x80 ,
93 | * n/(128p-1)%128 | 0x80 , ... n/(1280)%128 ];