From b7ddd0b8369d776f267b4fe8b5e62d3a61d4916b Mon Sep 17 00:00:00 2001 From: Mo Wang Date: Mon, 24 Oct 2011 21:36:59 -0700 Subject: [PATCH] add get --- demo/app/coffee/bst_app.coffee | 74 +++++++++++++++++-- demo/app/compiled/bst_app.js | 105 ++++++++++++++++++++++----- demo/binary_search_tree.html | 3 + demo/styles/css/main.css | 9 ++- demo/styles/less/main.less | 10 ++- src/coffee/binary_search_tree.coffee | 23 ++++-- src/compiled/binary_search_tree.js | 28 +++++-- 7 files changed, 212 insertions(+), 40 deletions(-) diff --git a/demo/app/coffee/bst_app.coffee b/demo/app/coffee/bst_app.coffee index 9f7ab0f..1b48e60 100644 --- a/demo/app/coffee/bst_app.coffee +++ b/demo/app/coffee/bst_app.coffee @@ -25,12 +25,14 @@ do (App) -> @_branchEnd = [@_x, @_y] @_payload = null @_highlightBranchTimer = null + @_highlightTimer = null # property @level = 0 # config @_animDuration = 250 + @_branchHighlightColor = "blue" _render.call this _registerEventHandler.call this @@ -70,12 +72,30 @@ do (App) -> @_centerLine.attr props this.highlightBranch(false) + + highlight: (stopOldAnim = true)-> + clearTimeout @_highlightTimer + @_leaf.stop() if stopOldAnim + + highlightColor = @_branchHighlightColor + @_leaf.attr { + fill: highlightColor + } + + highlightAnim = Raphael.animation { + fill: "black" + }, 1000, "<>" + + @_highlightTimer = setTimeout (=> + @_leaf.animate highlightAnim + ), 1000 + highlightBranch: (stopOldAnim = true)-> clearTimeout @_highlightBranchTimer @_branch.stop() if stopOldAnim - highlightColor = "blue" + highlightColor = @_branchHighlightColor @_branch.attr { stroke: highlightColor } @@ -160,7 +180,6 @@ do (App) -> @_leaf.attr { stroke: "white" fill: "black" - opacity: 0.4 } @_label.attr { @@ -290,6 +309,25 @@ do (App) -> } get: (key) -> + traceStr = "from" + value = @_data.get key, (item)-> + branch = "found" + switch item.branch + when -1 then branch = "left=>" + when 1 then branch = "right=>" + + traceStr += " Leaf #{item.key} #{branch}" + item.value.highlightBranch() + + traceStr += " dead end" unless value? + found = value? + _triggerLog.call this, { + type: "get" + message: traceStr + found: found + key: key + } + value clear: -> # clear all leafs from @_data @@ -388,19 +426,37 @@ $ -> when "log" $log.text e.message if e.subtype is "create" - $log.removeClass "update" if $log.hasClass "update" + $log.removeClass "negative" + $log.addClass "positive" else if e.subtype is "update" - $log.addClass "update" unless $log.hasClass "update" + $log.removeClass "negative positive" when "trace" $trace.text e.message if e.subtype is "create" - $trace.removeClass "update" if $trace.hasClass "update" + $trace.removeClass "negative" + $trace.addClass "positive" else if e.subtype is "update" - $trace.addClass "update" unless $trace.hasClass "update" + $trace.removeClass "negative positive" + when "get" + $trace.text e.message + found = e.found + logMessage = "found Leaf #{e.key}" + logMessage = "cannot " + logMessage unless found + $log.text logMessage + if found + $trace.removeClass "negative positive" + $log.removeClass "negative positive" + else + $trace.removeClass "positive" + $log.removeClass "positive" + $trace.addClass "negative" + $log.addClass "negative" + $key_select = $('#key_select') $value_input = $('#value_input') $add_button = $('#add_button') + $get_button = $('#get_button') $log = $('#bst-demo .log') $trace = $('#bst-demo .trace') @@ -413,6 +469,12 @@ $ -> value = "Leaf #{key}" if value is "" bstDemo.put key, value + $get_button.click (e)-> + e.preventDefault() + key = $key_select.val() + leaf = bstDemo.get key + leaf.highlight() if leaf? + $(document).bind "keypress", (e)-> if 48 <= e.keyCode <= 57 key = e.keyCode - 48 diff --git a/demo/app/compiled/bst_app.js b/demo/app/compiled/bst_app.js index b5fec1f..4bb6016 100644 --- a/demo/app/compiled/bst_app.js +++ b/demo/app/compiled/bst_app.js @@ -29,8 +29,10 @@ this._branchEnd = [this._x, this._y]; this._payload = null; this._highlightBranchTimer = null; + this._highlightTimer = null; this.level = 0; this._animDuration = 250; + this._branchHighlightColor = "blue"; _render.call(this); _registerEventHandler.call(this); } @@ -74,6 +76,26 @@ } return this.highlightBranch(false); }; + Leaf.prototype.highlight = function(stopOldAnim) { + var highlightAnim, highlightColor; + if (stopOldAnim == null) { + stopOldAnim = true; + } + clearTimeout(this._highlightTimer); + if (stopOldAnim) { + this._leaf.stop(); + } + highlightColor = this._branchHighlightColor; + this._leaf.attr({ + fill: highlightColor + }); + highlightAnim = Raphael.animation({ + fill: "black" + }, 1000, "<>"); + return this._highlightTimer = setTimeout((__bind(function() { + return this._leaf.animate(highlightAnim); + }, this)), 1000); + }; Leaf.prototype.highlightBranch = function(stopOldAnim) { var highlightAnim, highlightColor; if (stopOldAnim == null) { @@ -83,7 +105,7 @@ if (stopOldAnim) { this._branch.stop(); } - highlightColor = "blue"; + highlightColor = this._branchHighlightColor; this._branch.attr({ stroke: highlightColor }); @@ -174,8 +196,7 @@ _render = function() { this._leaf.attr({ stroke: "white", - fill: "black", - opacity: 0.4 + fill: "black" }); this._label.attr({ fill: "white", @@ -306,7 +327,34 @@ message: traceStr }); }; - BSTDemo.prototype.get = function(key) {}; + BSTDemo.prototype.get = function(key) { + var found, traceStr, value; + traceStr = "from"; + value = this._data.get(key, function(item) { + var branch; + branch = "found"; + switch (item.branch) { + case -1: + branch = "left=>"; + break; + case 1: + branch = "right=>"; + } + traceStr += " Leaf " + item.key + " " + branch; + return item.value.highlightBranch(); + }); + if (value == null) { + traceStr += " dead end"; + } + found = value != null; + _triggerLog.call(this, { + type: "get", + message: traceStr, + found: found, + key: key + }); + return value; + }; BSTDemo.prototype.clear = function() {}; BSTDemo.prototype.log = function(fn) { return this._logHandlers.push(fn); @@ -401,38 +449,52 @@ return App.BSTDemo = BSTDemo; })(App); $(function() { - var $add_button, $key_select, $log, $trace, $value_input, bstDemo; + var $add_button, $get_button, $key_select, $log, $trace, $value_input, bstDemo; bstDemo = new App.BSTDemo("bst-demo"); bstDemo.log(function(e) { + var found, logMessage; switch (e.type) { case "log": $log.text(e.message); if (e.subtype === "create") { - if ($log.hasClass("update")) { - return $log.removeClass("update"); - } + $log.removeClass("negative"); + return $log.addClass("positive"); } else if (e.subtype === "update") { - if (!$log.hasClass("update")) { - return $log.addClass("update"); - } + return $log.removeClass("negative positive"); } break; case "trace": $trace.text(e.message); if (e.subtype === "create") { - if ($trace.hasClass("update")) { - return $trace.removeClass("update"); - } + $trace.removeClass("negative"); + return $trace.addClass("positive"); } else if (e.subtype === "update") { - if (!$trace.hasClass("update")) { - return $trace.addClass("update"); - } + return $trace.removeClass("negative positive"); + } + break; + case "get": + $trace.text(e.message); + found = e.found; + logMessage = "found Leaf " + e.key; + if (!found) { + logMessage = "cannot " + logMessage; + } + $log.text(logMessage); + if (found) { + $trace.removeClass("negative positive"); + return $log.removeClass("negative positive"); + } else { + $trace.removeClass("positive"); + $log.removeClass("positive"); + $trace.addClass("negative"); + return $log.addClass("negative"); } } }); $key_select = $('#key_select'); $value_input = $('#value_input'); $add_button = $('#add_button'); + $get_button = $('#get_button'); $log = $('#bst-demo .log'); $trace = $('#bst-demo .trace'); $add_button.click(function(e) { @@ -446,6 +508,15 @@ } return bstDemo.put(key, value); }); + $get_button.click(function(e) { + var key, leaf; + e.preventDefault(); + key = $key_select.val(); + leaf = bstDemo.get(key); + if (leaf != null) { + return leaf.highlight(); + } + }); return $(document).bind("keypress", function(e) { var key, value, _ref; if ((48 <= (_ref = e.keyCode) && _ref <= 57)) { diff --git a/demo/binary_search_tree.html b/demo/binary_search_tree.html index bf4a5e1..86fe9d6 100644 --- a/demo/binary_search_tree.html +++ b/demo/binary_search_tree.html @@ -45,6 +45,9 @@

Binary Search Tree Demo

  • +
  • + +
  • Notes: You can press number keys 0-9 to add leafs.

    diff --git a/demo/styles/css/main.css b/demo/styles/css/main.css index de8dbc9..51db6ca 100644 --- a/demo/styles/css/main.css +++ b/demo/styles/css/main.css @@ -90,13 +90,16 @@ top: 0; font-size: 20px; font-weight: bold; - color: red; + color: yellow; background: black; padding: 4px; margin: 10px; } -#bst .log.update, #bst .trace.update { - color: yellow; +#bst .log.positive, #bst .trace.positive { + color: green; +} +#bst .log.negative, #bst .trace.negative { + color: red; } #bst .trace { font-size: 16px; diff --git a/demo/styles/less/main.less b/demo/styles/less/main.less index a37fd4d..d729f69 100644 --- a/demo/styles/less/main.less +++ b/demo/styles/less/main.less @@ -112,13 +112,17 @@ top: 0; font-size: 20px; font-weight: bold; - color: red; + color: yellow; background: black; padding: 4px; margin: 10px; - &.update { - color: yellow; + &.positive { + color: green; + } + + &.negative { + color: red; } } diff --git a/src/coffee/binary_search_tree.coffee b/src/coffee/binary_search_tree.coffee index 9cbae91..a2f9dcf 100644 --- a/src/coffee/binary_search_tree.coffee +++ b/src/coffee/binary_search_tree.coffee @@ -22,9 +22,9 @@ class BST @_root = _put.call this, @_root, key, value, fn # return value, or return null if nothing found - get: (key) -> + get: (key, fn) -> return null unless key? - _get @_root, key + _get @_root, key, fn # return the size of the bst size: -> @@ -41,16 +41,29 @@ class BST # private - _get = (node, key) -> + _get = (node, key, fn) -> return null unless node? + branch = 0 if node.key > key - return _get node.left, key + branch = -1 + _getCallback.call this, node, branch, fn + return _get node.left, key, fn else if node.key < key - return _get node.right, key + branch = 1 + _getCallback.call this, node, branch, fn + return _get node.right, key, fn else + _getCallback.call this, node, branch, fn return node.value + _getCallback = (node, branch, fn)-> + fn.call this, { + branch: branch + key: node.key + value: node.value + } if fn? + _put = (node, key, value, fn) -> branch = 0 oldVal; diff --git a/src/compiled/binary_search_tree.js b/src/compiled/binary_search_tree.js index 9387460..1ebdfdc 100644 --- a/src/compiled/binary_search_tree.js +++ b/src/compiled/binary_search_tree.js @@ -12,7 +12,7 @@ return Node; })(); BST = (function() { - var _get, _inOrderIterate, _postOrderIterate, _preOrderIterate, _put, _size; + var _get, _getCallback, _inOrderIterate, _postOrderIterate, _preOrderIterate, _put, _size; function BST() { this._root = null; } @@ -22,11 +22,11 @@ } return this._root = _put.call(this, this._root, key, value, fn); }; - BST.prototype.get = function(key) { + BST.prototype.get = function(key, fn) { if (key == null) { return null; } - return _get(this._root, key); + return _get(this._root, key, fn); }; BST.prototype.size = function() { return _size(this._root); @@ -41,18 +41,34 @@ return _inOrderIterate.call(this, this._root, fn); } }; - _get = function(node, key) { + _get = function(node, key, fn) { + var branch; if (node == null) { return null; } + branch = 0; if (node.key > key) { - return _get(node.left, key); + branch = -1; + _getCallback.call(this, node, branch, fn); + return _get(node.left, key, fn); } else if (node.key < key) { - return _get(node.right, key); + branch = 1; + _getCallback.call(this, node, branch, fn); + return _get(node.right, key, fn); } else { + _getCallback.call(this, node, branch, fn); return node.value; } }; + _getCallback = function(node, branch, fn) { + if (fn != null) { + return fn.call(this, { + branch: branch, + key: node.key, + value: node.value + }); + } + }; _put = function(node, key, value, fn) { var branch, newNode, oldVal; branch = 0;