Показать сообщение отдельно
  #1 (permalink)  
Старый 13.10.2017, 10:19
Новичок на форуме
Отправить личное сообщение для d1ver Посмотреть профиль Найти все сообщения от d1ver
 
Регистрация: 25.09.2017
Сообщений: 9

Бинарное древо (отрисовка), объекты
Всем здравствуйте.
Есть некоторый код:

<script type="text/javascript">
function drawPoly (id, arr) { //id тега <canvas> и массив координат
	var canvas = document.getElementById(id).getContext('2d');
	// Отрисовка
	canvas.clearRect(0,0,500,400);
	canvas.beginPath();
	clear_all();

	for (var i = 0; i < arr.length; i++) {
*!*
		canvas.strokeRect(arr[`${i}`].x + 250, arr[`${i}`].y * 10, 5, 5);

		console.log("x: " + arr[`${i}`].x + " y: " + arr[`${i}`].y);
*/!*
	}
}

function clear_all (){
	console.clear();
}

function BinarySearchTree() {
    this.root = null;
    this.index = 0;
}

BinarySearchTree.prototype.add = function(value) {
    var currentNode = this.makeNode(value);
    if (!this.root) {
        this.root = currentNode;
    } else {
        this.insert(currentNode);
    }
    return this;
};

BinarySearchTree.prototype.makeNode = function(value) {
    var node = {};
    node.value = value;
    node.info = {};
    node.left = null;
    node.right = null;
	node.parent = null;
	node.depth = 0;
	node.drawPoint = {
		x: 0,
		y: 0
	}
	node.index = this.index;
	this.index += 1;
    return node;
};

BinarySearchTree.prototype.insert = function(currentNode) {
    var value = currentNode.value;

    var traverse = function(node) {
        //if value is equal to the value of the node, ignore
        //and exit function since we don't want duplicates
        if (value === node.value) {
            return;
        } else if (value > node.value) {
            if (!node.right) {
                node.right = currentNode;
				node.depth++;
                return;
            } else
                traverse(node.right);
        } else if (value < node.value) {
            if (!node.left) {
                node.left = currentNode;
				node.depth++;
                return;
            } else
                traverse(node.left);
        }
    };
    traverse(this.root);
};


BinarySearchTree.prototype.setDepth = function() {
    var node = this.root;
    var maxDepth = 0;
    var traverse = function(node, depth) {
        if (!node) return null;
        if (node) {
            maxDepth = depth > maxDepth ? depth : maxDepth;
			node.depth = depth;
			//set parent too
			if (node.right){
				(node.right).parent = node;
			}
			if (node.left){
        		(node.left).parent = node;
        	}
            traverse(node.left, depth + 1);
            traverse(node.right, depth + 1);
        }
    };
    traverse(node, 1);
};

BinarySearchTree.prototype.maxDepth = function() {
    var node = this.root;
    var maxDepth = 0;
    var traverse = function(node) {
        if (!node) return null;
        if (node) {
            maxDepth = node.depth > maxDepth ? node.depth : maxDepth;
            traverse(node.left);
            traverse(node.right);
        }
    };
    traverse(node, 0);
    return maxDepth;
};

BinarySearchTree.prototype.setDrawPoint = function(maxDepth, resizer) {
    var node = this.root;
    var parentX, coef;
    var traverse = function(node, left) {
        if (!node) return null;
        if (node) {
*!*
        	parentX = node.parent ? (node.parent).drawPoint.x : 0;
        	parentX = left ? - parentX : parentX;
        	coef = left ? -coef : coef;
			node.drawPoint.x = parentX + Math.pow(2, maxDepth - node.depth);
			node.drawPoint.y = node.depth + resizer;
*/!*
            traverse(node.left, true);
            traverse(node.right);
        }
    };
    traverse(node);
};

BinarySearchTree.prototype.checkDrawPoint = function() {
    var node = this.root;
    var drawPoint = {};
    var counter = 0;
    var traverse = function(node) {
        if (!node) return null;
        if (node) {
        	*!*drawPoint[`${node.index}`] = node.drawPoint;*/!*
        	counter++;
            traverse(node.left);
            traverse(node.right);
        }
    };
    traverse(node, 0);
    drawPoint.length = counter;
    return drawPoint;
};


BinarySearchTree.prototype.setInfo = function() {
    var node = this.root;
    var traverse = function(node) {
        if (!node) return null;
        if (node) {
		    node.info = {};
			node.info.depth = node.depth;
			node.info.index = node.index;
			node.info.parent = node.parent;
			delete node.parent;
			delete node.depth;
			delete node.index;
            traverse(node.left);
            traverse(node.right);
        }
    };
    traverse(node, 0);
};

function BinaryTreeConstructor (num) {
	var tree = new BinarySearchTree();
	for (let i = 0; i < num; i++) {
		tree.add(parseInt((Math.random()*1000).toFixed(1)));
	}
	tree.setDepth();
	*!*tree.setDrawPoint(tree.maxDepth(), 0);*/!*
        delete(tree.index);
	return tree;
}

function createCoordArray(num) {
	var tree = new BinaryTreeConstructor(num);
	*!*var coordArray = tree.checkDrawPoint();*/!*
	return coordArray;
}





</script>
 
<form>
<canvas style='border:1px dashed #888;' id='canvasId' width='500' height='400'>
Извините, тег Canvas недоступен!
</canvas>
<br>
<input style="width:auto;" type="button" value="Draw" onclick="drawPoly('canvasId', createCoordArray(document.getElementById('count').value))">
<input style="width:auto;" type="text" value="10" id="count">
</form>



Суть проблемы: при работе функции отрисовки на большом кол-ве элементов вылезает ошибка

Uncaught TypeError: Cannot read property 'x' of undefined
    at drawPoly (Отрисовка.html:16)// в текущем документе - 10
    at HTMLInputElement.onclick (Отрисовка.html:207)

Почему вылезает - не знаю, замучился уже гадать.
Подскажите, пожалуйста, причину, и способ исправить.

Суть второй проблемы: как правильно менять координаты ветки дерева, чтобы точки друг-друга не перекрывали и линии (которые я добавлю позже) не пересекались?
Мое решение, реализованное в коде, пока не проходит (по логике вещей, второй этаж сверху должен рисоваться симметрично, ну и т.д.).
Спасибо.

P.S. Извините за большую пасту, спойлеров не нашел.

Последний раз редактировалось d1ver, 13.10.2017 в 11:10. Причина: Исправление ошибок...
Ответить с цитированием