在线生成二叉树(基于EaselJS(canvas))
学习二叉树的时候,老在本子上画二叉树好麻烦。其实就想看下树结构。最近html5蛮火的,就用canvas和EaselJS.js(开发flash公司开发的插件)插件实现了个。大家随便用吧。
这是个什么东西呢?其实就是你提供这样一串数组 30,25,19,37,35,40,39,34,22,42,36 输入到input控件中,点击按钮,在canvas生成二叉树画面。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title> </head>
<body>
<div>
<ul>
<li>请用,(单字节)分割数字,0-999之间的数字</li>
<li>">"一个一个节点插入</li>
<li>">>"一次性插入所有节点</li>
<li>双击节点删除</li>
</ul>
</div>
<div>
<input id="numbertext" title="" placeholder="请用,(单字节)分割数字,0-999之间的数字" value="30,25,19,37,35,40,39,34,22,42,36" />
<input type="button" value=">" title="增加一个节点" onclick="AddOneNumber()" />
<input type="button" value=">>" title="一次性增加所有节点" onclick="AddAllNumber()" />
</div>
<br />
<canvas id="gameView" style="background-color:antiquewhite"> </canvas> <script src="https://code.createjs.com/easeljs-0.8.2.min.js"></script>
<script src="BinaryTree.js"></script>
<script src="app.js"></script>
</body>
</html>
BinaryTree.js
var Node = function (_date,_parent) {
this.Data = _date;
this.Parent = _parent;
this.LeftNode = null;
this.RightNode = null;
}
var BinaryTree = function () {
this.Root = null;//根节点
this.Insert = function (insertValue) {
if (this.Root == null) {
this.Root = new Node(insertValue,null);
return;
}
var node = this.Root;
while (true) {
if (node.Data > insertValue) {
if (node.LeftNode == null) {
node.LeftNode = new Node(insertValue,node);
break;
} else {
node = node.LeftNode;
}
} else if (node.Data < insertValue) {
if (node.RightNode == null) {
node.RightNode = new Node(insertValue, node);
break;
} else {
node = node.RightNode;
}
} else {
break;
}
}
};
var maxLevel;
var level;
this.Level = function () {
maxLevel = 0;
level = 0;
return levels(this.Root);
}
function levels(node) {
if (node.LeftNode != null) {
level++;
levels(node.LeftNode);
}
maxLevel = Math.max(maxLevel, level);
if (node.RightNode != null) {
level++;
levels(node.RightNode);
}
level--;
return maxLevel;
}
this.SetPoint = function () {
var thisMaxLevel = this.Level();
var childQuanty = Math.pow(2, thisMaxLevel);
this.Root.nodeLevel = 0;
this.Root.nodePoint = 0;
if (this.Root.LeftNode != null)
{
setPointsLeft(this.Root.LeftNode, -1 * childQuanty / 2, 0, thisMaxLevel - 1);
}
if (this.Root.RightNode != null)
{
setPointsRight(this.Root.RightNode, childQuanty / 2, 0, thisMaxLevel - 1);
}
}
function setPointsLeft(node, point, levels, thisMaxLevel) {
++levels;
node.nodeLevel = levels;
node.nodePoint = point;
if (node.LeftNode != null) {
setPointsLeft(node.LeftNode, point - Math.pow(2, thisMaxLevel - levels), levels, thisMaxLevel);
}
if (node.RightNode != null) {
setPointsLeft(node.RightNode, point + Math.pow(2, thisMaxLevel - levels), levels, thisMaxLevel);
}
}
function setPointsRight(node, point, levels, thisMaxLevel) {
++levels;
node.nodeLevel = levels;
node.nodePoint = point;
if (node.LeftNode != null) {
setPointsRight(node.LeftNode, point - Math.pow(2, thisMaxLevel - levels), levels, thisMaxLevel);
}
if (node.RightNode != null) {
setPointsRight(node.RightNode, point + Math.pow(2, thisMaxLevel - levels), levels, thisMaxLevel);
}
}
this.PreOrder = function (funs) {
preOrder(this.Root, funs);
}
function preOrder(node, funs) {
funs(node);
if (node.LeftNode != null) {
preOrder(node.LeftNode, funs);
}
if (node.RightNode != null) {
preOrder(node.RightNode, funs);
}
}
this.Search = function (number)
{
return search(this.Root, number);;
}
function search(node,number)
{
if (node == null)
{
return null;
}
if (node.Data>number)
{
return search(node.LeftNode,number);
} else if (node.Data < number) {
return search(node.RightNode, number);
} else {
return node;
}
}
this.Remove = function (number)
{
var node = this.Search(number);
if (node != null)
{
remove.call(this,node);
}
}
function remove(node)
{
var child, parent;
if (node.LeftNode != null && node.RightNode != null) {
var tempNode = findMin(node.RightNode);
if (node.Parent == null) {
this.Root = tempNode;
} else {
if (node.Parent.LeftNode == node) {
node.Parent.LeftNode = tempNode;
} else {
node.Parent.RightNode = tempNode;
}
}
child = tempNode.RightNode;
parent = tempNode.Parent;
if (parent.Data == node.Data) {
parent = tempNode;
} else {
if (child != null) {
child.Parent = parent;
}
parent.LeftNode = child;
tempNode.RightNode = node.RightNode;
node.RightNode.Parent = tempNode;
}
tempNode.Parent = node.Parent;
tempNode.LeftNode = node.LeftNode;
node.LeftNode.Parent = tempNode;
} else {
if (node.LeftNode != null) {
child = node.LeftNode;
} else {
child = node.RightNode;
}
parent = node.Parent;
if (child != null) {
child.Parent = parent;
}
if (parent != null) {
if (parent.LeftNode!=null && parent.LeftNode.Data == node.Data) {
parent.LeftNode = child;
} else {
parent.RightNode = child;
}
} else {
this.Root = child;
}
}
node = null;
}
this.FindMin = function ()
{
findMin(this.Root);
}
function findMin(node)
{
if (node.LeftNode == null)
{
return node;
}
return findMin(node.LeftNode);
}
this.FindMax = function ()
{
return findMax(this.Root);
}
function findMax(node)
{
if (node.RightNode == null)
{
return node;
}
return findMax(node.RightNode);
}
}
app.js
/// <reference path="C:\Users\思远\documents\visual studio 2013\Projects\ApplicationHost\WebApplication1\easeljs-0.8.2.min.js" />
var gameView = document.getElementById("gameView");
var stage = new createjs.Stage(gameView);
var height = 50;//节点之间的高
var width = 15;//节点之间的宽
var tops = 40;//根节点离顶部的距离
var foot = 40;//树离底部距离
var spacing = 30;//树分别离两边的间距
var tree = new BinaryTree();
function AddOneNumber()
{
var numbertext = document.getElementById("numbertext").value;
var oneNums = numbertext.match(/[1-9][0-9]{0,2}\,?/);
document.getElementById("numbertext").value = numbertext.replace(/[1-9][0-9]{0,2}\,?/, "");
var num = (oneNums+"").match(/[1-9][0-9]{0,2}/);
if (num)
{
tree.Insert(parseInt(num));
RenewTreeNode();
}
}
function AddAllNumber()
{
while (true) {
AddOneNumber();
var numbertext = document.getElementById("numbertext").value;
if (!/[1-9][0-9]{0,2}/.test(numbertext))
{
break;
}
}
}
function DeleteNumber(number)
{
tree.Remove(parseInt(number));
RenewTreeNode();
}
function RenewTreeNode(number) {
stage.removeAllChildren();
SetCanvasWidthHeight(tree);
tree.SetPoint();
tree.PreOrder(SetPreOrder);
}
function SetCanvasWidthHeight(tree) {
var level = tree.Level();
gameView.height = height * level + tops + foot;
gameView.width = Math.pow(2, level+1) * width + spacing*2;
}
function SetPreOrder(node) {
var container = CreateNode(
node.Data,
gameView.width / 2 + width * node.nodePoint,
(node.nodeLevel * height + parseInt(tops)),
"red");
stage.addChild(container);
if (node.Parent != null) {
var line = CreateLineTo(
(gameView.width / 2 + width * node.Parent.nodePoint),
(node.Parent.nodeLevel * height + parseInt(tops)),
(node.Data, gameView.width / 2 + width * node.nodePoint),
(node.nodeLevel * height + parseInt(tops)));
stage.addChild(line);
}
stage.update();
}
//color=gray red yellow blue black
function CreateNode(number, x, y, color) {
var textX = 0;
if (number < 10) {
textX = -5;
} else if (number > 9 && number < 100) {
textX = -9;
} else {
textX = -14;
}
var text = new createjs.Text(number, "16px Arial", "#fff");
text.x = textX;
text.y = -8;
var graphics = new createjs.Graphics();
graphics.setStrokeStyle(1);
graphics.beginStroke(createjs.Graphics.getRGB(0, 0, 255));
graphics.beginFill(color);
graphics.drawCircle(0, 0, 15);
var shape = new createjs.Shape(graphics);
var container = new createjs.Container();
container.x = x;
container.y = y;
container.addChild(shape, text);
container.addEventListener("dblclick", function () {
DeleteNumber(text.text);
});
return container;
}
function CreateLineTo(fatherNodex, fatherNodey, childrenNodex, childrenNodey) {
var sp = new createjs.Shape();
sp.graphics.s("blue").ss(2).mt(fatherNodex, fatherNodey + 15).lt(childrenNodex, childrenNodey - 15).es();//线
return sp;
}
在线生成二叉树(基于EaselJS(canvas))的更多相关文章
- 基于HTML5 Canvas的网页画板实现教程
HTML5的功能非常强大,尤其是Canvas的应用更加广泛,Canvas画布上面不仅可以绘制任意的图形,而且可以实现多种多样的动画,甚至是一些交互式的应用,比如网页网版.这次我们要来看的就是一款基于H ...
- 一款基于HTML5 Canvas的画板涂鸦动画
今天给各网友分享一款基于HTML5 Canvas的画板涂鸦动画.记得之前我们分享过一款HTML5 Canvas画板工具,可以切换不同的笔刷,功能十分强大.本文今天要再来分享一款基于HTML5 Canv ...
- 在线白板,基于socket.io的多人在线协作工具
首发:个人博客,更新&纠错&回复 是昨天这篇博文留的尾巴,socket.io库的使用练习,成品地址在这里. 代码已经上传到github,传送门.可以开俩浏览器看效果. 现实意义是俩人在 ...
- 基于html5 canvas和js实现的水果忍者网页版
今天爱编程小编给大家分享一款基于html5 canvas和js实现的水果忍者网页版. <水果忍者>是一款非常受喜欢的手机游戏,刚看到新闻说<水果忍者>四周年新版要上线了.网页版 ...
- canvas-js贝塞尔曲线代码在线生成工具
详细内容请点击 canvas贝塞尔曲线代码在线生成工具 可以快速生成二次.三次贝塞尔曲线的源码生成器,方便经常使用到canvas画图的同学使用,可以直接预览效果随意画出自己想要的图像. 生成源码效果预 ...
- 基于HTML5 Canvas的线性区域图表教程
之前我们看到过很多用jQuery实现的网页图表,有些还是比较实用的.今天我们来介绍一款基于HTML5 Canvas的线性区域图表应用,这个图表应用允许你使用多组数据来同时展示,并且将数据结果以线性图的 ...
- canvas-js贝塞尔曲代码在线生成工具
canvas贝塞尔曲代码在线生成工具 可以快速生成二次.三次贝塞尔曲线的源码生成器,方便经常使用到canvas画图的同学使用,可以直接预览效果随意画出自己想要的图像. 生成源码效果预览: canvas ...
- 基于HTML5 Canvas实现用户交互
很多人都有这样的疑问,基于HTML5 Canvas实现的元素怎么和用户进行交互?在这里我们用到HT for Web(http://www.hightopo.com/guide/guide/core/b ...
- 基于html5 Canvas图表库 : ECharts
ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表.创新的拖拽重计算.数据视图.值 ...
随机推荐
- qq客服问题
angularJs会给ng-href的不正常跳转,会 添加unsafe的前缀.原因是angular对href是有安全检查的,只能生成它认为安全的链接.解决方法如下: 在config.js中注入 fun ...
- 四维dp 或者 剪枝 + dfs Codeforces Beta Round #6 (Div. 2 Only) D
http://codeforces.com/contest/6/problem/D 题目大意:有一队人,排成一列,每个人都有生命值,你每次可以攻击2~n位置的一个的人,假设每次攻击的位置为pos,那么 ...
- 使用Spring 3的@value简化配置文件的读取 (转)
Spring 3支持@value注解的方式获取properties文件中的配置值,大简化了读取配置文件的代码. 1.在applicationContext.xml文件中配置properties文件 & ...
- JS day01——window对象、执行顺序、线程模型
1.window对象 window对象表示当前浏览器的窗口,它是一个顶级对象,我们创建的所有对象.函数.变量都是window对象的成员. window对象自带了一些非常有用的方法.属性. window ...
- CentOS下载及版本选择-CentOS LiveCD、LiveDVD和BinDVD区别
1.CentOS系统镜像有两个,安装系统只用到第一个镜像即CentOS-6.x-i386-bin-DVD1.iso(32位)或者CentOS-6.x-x86_64-bin-DVD1.iso(64位), ...
- 最小点集覆盖/HDU2119
题目连接 先试一下题/?/ 最小点集覆盖=最大匹配 /*根据i.j建图,跑一边最大匹配 */ #include<cstdio> #include<cstring> using ...
- HTML5程序设计 Canvas API
检测浏览器支持情况 <script type="text/javascript"> try { document.createElement("Canvas& ...
- Linux环境下Android JNI程序的编译
尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8993493 在android开发中,有时候需要编写一些C/C++代码,这时候 ...
- javascript预编译
刚学前端的小白,第一次写博客,难免有点幼稚.以后每周写两次博客,慢慢积累. 笨鸟不必先飞,但一定是最后一个留下的.加油! JS的预编译定义 在一段程序执行前,js会把var和function这两个关键 ...
- html5 之本地数据存储
HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 cookie与webSt ...