定义树的节点:
Node = function(data) { var R = 15; this.x; this.y; this.data = data; this.parent = null; this.left = null; this.right = null; this.color = "lightblue"; this.getR = function() { return R; } this.setLeft = function(left) { this.left = left; if (left != null) this.left.parent = this; } this.setRight = function(right) { this.right = right; if (right != null) this.right.parent = this; } this.isLeft = function() { if (this.parent == null) return null; return this.parent.left == this; } this.isRight = function() { if (this.parent == null) return null; return this.parent.right == this; } this.toString = function() { return data; } // for avl this.getLeftAndRightLevel = function() { var left = 0; var right = 0; if (this.left != null) { left = this.left.getMaxLevel() - this.getLevel(); } if (this.right != null) { right = this.right.getMaxLevel() - this.getLevel(); } return {left: left, right: right} ; } this.getLevel = function() { return (this.parent == null ? 1 : this.parent.getLevel() + 1); } this.getMaxLevel = function() { var stack = new Array(); stack.push(this); var max = 0; while (stack.length > 0) { var d = stack.pop(); var l = d.getLevel(); if (l > max && d.left == null && d.right == null) { max = l; } if (d.left != null) stack.push(d.left); if (d.right != null) stack.push(d.right); } return max; }}初始化一些测试数据
var n = new Array(); this.init = function() { var m = Math.round(Math.random() * 30); for (var i=0; i<m; i++) { var k = Math.round(Math.random() * 1000); if (n.indexOf(k) == -1) { n.push(k); } } }显示树
var canvas = document.getElementById(canvasid); var a = new Array(); var stack = new Array(); stack.push(this.root); while (stack.length > 0) { var n = stack.shift(); a.push(n); if (n != null) { var h = n.getLevel(); var w = this.getLeftNumber(n); var x = w * 30 - n.getR() /2; var y = h * 30 - n.getR() /2; n.x = x; n.y = y; if (n.left != null) stack.push(n.left); if (n.right != null) stack.push(n.right); } } for (var i=0; i<a.length; i++) { var n = a[i]; if (n.parent != null) { var l = drawLine(n.x, n.y, n.parent.x, n.parent.y); canvas.appendChild(l); } } for (var i=0; i<a.length; i++) { var n = a[i]; var c = drawCircle(n.x, n.y, n); canvas.appendChild(c); var t = drawText(n.x, n.y, n); canvas.appendChild(t); } }定义画布
<div style="height:300px;overflow:auto"> <svg id="c" width="100%" version="1.1" xmlns="http://www.w3.org/2000/svg" /> </div> <div style="height:300px;overflow:auto"> <svg id="d" width="100%" version="1.1" xmlns="http://www.w3.org/2000/svg" /> </div> <div style="height:300px;overflow:auto"> <svg id="e" width="100%" version="1.1" xmlns="http://www.w3.org/2000/svg" /> </div>打印遍历树
this.disparray = function() { var r = new Array(); var stack = new Array(); var p = this.root; while (p!= null || stack.length != 0) { while (p != null ) { stack.push(p); p = p.left; } p = stack.pop(); r.push(p); p = p.right; } console.log(r.join(",") ); }执行
t = new Tree(); t.init(); t.BST(); t.disp("c"); t.disparray(); t.AVL(); t.disp("d"); t.disparray(); t.RBT(); t.disp("e"); t.disparray();二叉查找树this.BST = function() { // clear this.root = null; cachenodes = null; for (var i=0; i<n.length; i++) { var m = n[i]; var p = this.root; var parent = null; var left = true; while (p != null) { parent = p; if (m < p.data) { p = p.left; left = true; } else if (m>p.data) { p = p.right; left = false; } } if (parent == null) { this.root = new Node(m); } else { p = new Node(m); if (left) parent.setLeft(p); else parent.setRight(p); } } }二叉平衡树
function ll(node) { var parent = node.parent; var left = node.isLeft() ; var p = node.left; node.setLeft(node.left.right); p.setRight(node); if (left != null) { if (left) parent.setLeft(p); else parent.setRight(p); } else p.parent = null; return p; } function rr(node) { var parent = node.parent; var left = node.isLeft() ; var p = node.right; node.setRight(node.right.left); p.setLeft(node); if (left != null) { if (left) parent.setLeft(p); else parent.setRight(p); } else p.parent = null; return p; } function lr(node) { var parent = node.parent; var left = node.isLeft() ; var p = rr(node.left); p = ll(node); if (left != null) { if (left) parent.setLeft(p); else parent.setRight(p); } else p.parent = null; return p; } function rl(node) { var parent = node.parent; var left = node.isLeft() ; var p = ll(node.right); p = rr(node); if (left != null) { if (left) parent.setLeft(p); else parent.setRight(p); } else p.parent = null; return p; } this.AVL = function() { this.root = null; cachenodes = null; for (var i=0; i<n.length; i++) { var m = n[i]; var p = this.root; var parent = null; var path = new Array(); while (p != null ) { path.push(p); parent = p; if (m < p.data) { p = p.left; } else if (m>p.data) { p = p.right; } } if (parent == null) { this.root = new Node(m); continue ; } p = new Node(m); if (m < parent.data) parent.setLeft(p); else parent.setRight(p); // while (path.length > 0) { p = path.pop(); var l = p.getLeftAndRightLevel(); if (l.left - l.right > 1) { // ll or lr if (p.left.left != null) p = ll(p); else if (p.left.right != null) p = lr(p); } else if (l.right - l.left > 1 ) { // rr or rl if (p.right.right != null) p = rr(p); else if (p.right.left != null) p = rl(p); } if (path.length == 0) this.root = p; } } }红黑树
function lll(node) { var parent = node.parent; var left = node.isLeft() ; var p = node.right; node.setRight(p.left); p.setLeft(node); if (left != null) { if (left) parent.setLeft(p); else parent.setRight(p); } else p.parent = null; return p; } function rrr(node) { var parent = node.parent; var left = node.isLeft() ; var p = node.left; node.setLeft(p.right); p.setRight(node); if (left != null) { if (left) parent.setLeft(p); else parent.setRight(p); } else p.parent = null; return p; } this.RBT = function() { this.root = null; cachenodes = null; for (var i=0; i<n.length; i++) { var m = n[i]; if (this.root == null) { this.root = new Node(m); this.root.color = "grey"; continue ; } var p = this.root; var parent = null; while (p != null ) { parent = p; if (m < p.data) { p = p.left; } else if (m>p.data) { p = p.right; } } p = new Node(m); p.color = "red"; if (m < parent.data) parent.setLeft(p); else parent.setRight(p); // set color while (parent != null && parent.color == "red") { if (parent.isLeft() == true) { var fb = parent.parent.right; if (fb != null && fb.color == "red") { fb.color = "grey"; parent.color = "grey"; p.parent.parent.color = "red"; p = p.parent.parent; } else { if (p.isRight() == true) { p = p.parent; var t = lll(p); if (t.parent == null) this.root = t; } p.parent.color = "grey"; if (p.parent.parent != null) p.parent.parent.color = "red"; var t = rrr(p.parent.parent); if (t.parent == null) this.root = t; } } if (parent.isRight() == true) { var fb = parent.parent.left; if (fb != null && fb.color == "red") { fb.color = "grey"; parent.color = "grey"; p.parent.parent.color = "red"; p = p.parent.parent; } else { if (p.isLeft() == true) { p = p.parent; var t = rrr(p); if (t.parent == null) this.root = t; } p.parent.color = "grey"; if (p.parent.parent != null) p.parent.parent.color = "red"; var t = lll(p.parent.parent); if (t.parent == null) this.root = t; } } parent = p.parent; } this.root.color = "grey"; } }显示图,第一个是二叉查找数, 第二个是二叉平衡数,第三个是红黑树
F5
新闻热点
疑难解答