完全二叉树:
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
也就是说除了最底下一层可以不满,上面的层都得满节点,而且最底下一层也必须集中在最左边。可以说,右边有左边就一定满,下面有,上面就一定满。
完全二叉树非完全二叉树
非完全二叉树
用js写一个完全二叉树:
//写一个节点编号,因为完全二叉树遵循右边有左边一定满,下面有,上面一定满,但二叉树又是左小右大的插入规则,所以没有特定的一串值很难变成完全二叉树,所以我们给每个节点按顺序放上编号,如果前面的不存在,就给他一个null值以达到完全二叉树的规则;
带节点编号的完全二叉树从上图我们可以发现一个规律 左节点的编号是其父节点的编号乘2加1 右节点的编号是其父节点的编号乘2加2 掌握这个规律 对节点的插入就容易了很多
function Node(number,value){//number就是节点编号
this.value = value||null;
this.left = null;
this.right = null;
this.number = number||0;
this.add = function(value){
if(this.value == null){
this.value = value;
return 0;
}
if(value<this.value){
if(this.left!=null){
this.left.add(value);
}else{
num = 2*this.number+1;
this.left = new Node(num,value);
return num;
}
}else{
if(this.right!=null){
this.right.add(value);
}else{
num = 2*this.number+2;
this.right = new Node(num,value);
return num;//返回节点编号
}
}
} //这种插入节点的方法就是普通的加入节点的方法只是多返回一个节点编号 并不能构成完全二叉树,所以我们还要下一个补充不够的节点的方法
this.fullup = function(nodeId){
if(this.number<nodeId){//防止加多,所以先要判断是不是小于最后一个节点
if(this.left == null){//先找左
num = 2*this.number+1;
if(num<nodeId){//在判断一次 防止加多
this.left = new Node(num)
}else{
return;
}
}
this.left.fullup(nodeId);
if(this.right == null){//找右
num = 2*this.number+2;
if(num<nodeId){
this.right = new Node(num);
}else{
return;
}
}
this.right.fullup(nodeId);
}
}
//递归遍历 前几章有讲解 这章不多做解释了。
this.iterate=function(arr){
if(this.left!=null){
this.left.iterate(arr);
}
if(this.value!=null){
arr.push(this.value);
}
if(this.right!=null){
this.right.iterate(arr);
}
}
}
//创建一个完全二叉树的类 用来添加节点以及遍历节点
function CompleteTree(){
this.root=null;
this.add=function(value){
if(this.root!=null){
nodeId = this.root.add(value);
this.root.fullup(nodeId);
}else{
this.root = new Node(0,value);
}
}
this.iterate=function(){
arr = [];
this.root.iterate(arr);
return arr;
}
}
网友评论