首页 > Web开发 > 详细

基于EaselJS(canvas)生成二叉树

时间:2016-01-06 13:36:38      阅读:1349      评论:0      收藏:0      [点我收藏+]

学习二叉树的时候,老在本子上画二叉树好麻烦。其实就想看下树结构。最近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>
        <input id="numbertext" title="请用,(单字节)分割数字" placeholder="请用,(单字节)分割数字" 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,_paret) {
    this.Data = _date;
    this.Paret = _paret;
    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);
            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);
        }
    }
}

 

app.js

/// <reference path="C:\Users\思远\documents\visual studio 2013\Projects\ApplicationHost\WebApplication1\easeljs-0.8.2.min.js" />

 
var numbers = [];
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;//树分别离两边的间距

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)
    {
        numbers.push(parseInt(num));
        CreateTree();
    }
}

function AddAllNumber()
{
    while (true) {
        AddOneNumber();
        var numbertext = document.getElementById("numbertext").value;
        if (!numbertext)
        {
            break;
        }
    }
}
  
 
function CreateTree() {
    stage.removeAllChildren();

    var tree = new BinaryTree();
    for (var i = 0; i < numbers.length; i++) {
        tree.Insert(numbers[i]);
    }
    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.Paret != null) {
        var line = CreateLineTo(
            (gameView.width / 2 + width * node.Paret.nodePoint),
            (node.Paret.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);

    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)生成二叉树

原文:http://www.cnblogs.com/bbvi/p/5104916.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!