定义二叉树的存储结构
class BiTNode{
constructor(lchild,data,rchild){
this.lchild=lchild;
this.data=data;
this.rchild=rchild;
}
setLchild(lchild){
this.lchild = lchild;
}
setRchild(rchild){
this.rchild = rchild;
}
}
构造二叉树的代码
/**
*
* @param {*string 先序二叉树字符串序列,其中空树用字符#表示 } s
* @returns 二叉树的根节点
*/
function CreateBiTree(s){
//非递归建立二叉树
//s="abc##de#g##f###"; //测试序列
s = s.trim();
let root=new BiTNode(null,s[0],null,null);
let stack=[root];
for(let i=1;i<s.length;i++){
let biNode = new BiTNode(null,s[i],null,null);
if(stack[stack.length-1].data!="#"){
if(biNode.data!="#"){//如果为空则不添加
stack[stack.length-1].setLchild(biNode);
}
}else{
stack.pop();
let cur=stack.pop();
if(biNode.data!="#"){
if(cur.data != "#"){
cur.setRchild(biNode);
}else{
//空树不予许设置字树,出现则说明用户输入的字符序列错误
return null;
}
}
}
stack.push(biNode);
}
return root;
}
按层次遍历二叉树:用一个变量nextLastNode来保存下一层的最后一个结点。用队列来保存遍历过的结点,先判断刚出队列的结点(即curNode)其左右子树是否为空,不为空则进入队列,然后再判断当前结点是否为下一层的最后一个结点,如果是则更新nextLastNode,最后更新curNode;
/**
* 按层次遍历二叉树,每遍历完一层二叉树 输出 '换一行'
* @param {* BiTNode} root
*/
function levelOrderTraversal(root) {
let queue = []; //用队列来保存结点
let curNode = root; //当前正在遍历的结点
let nextLastNode = root; //指向下一层最后一个结点
while(curNode != null) {`在这里插入代码片`
alert(curNode.data); //输出当前数据
if(curNode.lchild != null) {
queue.push(curNode.lchild);
}
if(curNode.rchild != null) {
queue.push(curNode.rchild);
}
if(curNode == nextLastNode) {
//如果右子树为null,则下一层最后一个结点的最后一个结点是当前结点的左子树,
//否则是下一层最后一个结点的最后一个结点是当前结点的右子树
nextLastNode = curNode.rchild == null ? curNode.lchild : curNode.rchild;
alert("换一行");
}
curNode = queue.shift();
}
}
后序遍历非递归二叉树:用栈来保存遍历后的结点,给入栈的结点添加一个标志位,用于标志结点的访问状态,该标志位true说明当前遍历的结点是该入栈结点的左子树那部分,反之则为右子树。
/**
* 后序遍历非递归二叉树
* @param {* 二叉树根结点} root
* @returns 保存遍历结果的数组
*/
function PostOrderTraverse(root){
let stack=[]; //保存遍历过得结点
let isLeftChildTraverse = []; //用于标志是否正在遍历左子树
let curTreeNode = root; //当前正在遍历的结点
let list = []; //用于存放遍历结果
while(stack.length > 0 || curTreeNode != null) {
while(curTreeNode != null) {
stack.push(curTreeNode);
isLeftChildTraverse.push(true);
curTreeNode = curTreeNode.lchild;
}
curTreeNode = stack[stack.length-1].rchild == null ? null : stack[stack.length-1].rchild;
isLeftChildTraverse[isLeftChildTraverse.length-1] = false;
while(curTreeNode == null && isLeftChildTraverse[isLeftChildTraverse.length-1] == false){
list.push(stack.pop().data);
isLeftChildTraverse.pop();
}
}
// alert("list: "+list.join(","));
return list;
}
求二叉树深度
/**
*
* @param {*二叉树的根节点} root
* @returns 二叉树的深度
*/
function TreeDepth(T) {
let deep = 0;
if(T){
let leftdeep = TreeDepth(T.lchild);
let rightdeep = TreeDepth(T.rchild);
deep = leftdeep>=rightdeep?leftdeep+1:rightdeep+1;
}
return deep;
}