首页 > 学院 > 开发设计 > 正文

BST数,AVL树,红黑树

2019-11-08 03:03:43
字体:
来源:转载
供稿:网友

定义树的节点:

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


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表