基础二叉树

class Node{
    constructor(){
        this.value=null;
        this.left=null;
        this.right=null;
    }
    make(Node){
        this.value=Node.value;
        this.left=Node.left;
        this.right=Node.right;
    }
}
class NodeS{
    constructor(){
        this.value;
        this.left;
        this.right;
        this.father;
    }
}
class JST{
    constructor(){
        this.isST=null;
        this.max=null;
        this.min=null;
    }
}
class JFT{
    constructor(){
        this.isFT=null;
        this.height=null;
        this.nodeSum=null;
    }
}
class JSBT{
    constructor(){
        this.isSB=null;
        this.height=null;
    }
}
//递归遍历
function RePre(head){
    if(head==null){
        return;
    }
    console.log(head.value);//先序
    RePre(head.left);
    //console.log(head.value);//中序
    RePre(head.right);
    //console.log(head.value);//后序
}
//非递归先序
function Pre(head){
    let stack=new Array();
    stack.unshift(head);
    while(stack.length){
        let tmp=stack.shift();
        console.log(tmp.value);
        if(tmp.right){
            stack.unshift(tmp.right);
        }
        if(tmp.left){
            stack.unshift(tmp.left);
        }
    }
}
//非递归后续
function Post(head){
    let stack1=new Array();
    let stack2=new Array();
    stack1.unshift(head);
    while(stack1.length){
        let tmp=stack1.shift();
        stack2.unshift(tmp);//放入收集栈中
        if(tmp.left){
            stack1.unshift(tmp.left);
        }
        if(tmp.right){
            stack1.unshift(tmp.right);
        }
    }
    while(stack2.length){
        let tmp =stack2.shift();
        console.log(tmp.value);
    }
}
//非递归中序
function Med(head){
    let stack=new Array();
    let tmp=head.left;
    stack.unshift(head);
    while(tmp){
        stack.unshift(tmp);//把左节点全部压入栈
        tmp=tmp.left;
    }
    while(stack.length){
        tmp=stack.shift();
        console.log(tmp.value);
        if(tmp.right){
            tmp=tmp.right;
            while(tmp){
                stack.unshift(tmp);
                tmp=tmp.left;
            }
        }
    }
}
//用队列实现宽度优先搜索
function BFS(head){
    let queue=new Array();
    queue.push(head);
    while(queue.length){
        let tmp=queue.shift();
        console.log(tmp.value);
        if(tmp.left){
            queue.push(tmp.left);
        }
        if(tmp.right){
            queue.push(tmp.right);
        }
    }
}
//求树的最大宽度
//哈希表快速解决
function GetWidth(head){
    let LevMap =new Map();
    let max=-1;
    let curlev=0;let cursum=0;
    let que=new Array();
    que.push(head);
    LevMap.set(head,0);
    while(que.length){
        let tmp=que.shift();
        if(LevMap.get(tmp)==curlev){
            cursum++;
        }
        else{
            max=cursum>max?cursum:max;
            curlev++;
            cursum=1;
        }
        if(tmp.left){
            LevMap.set(tmp.left,curlev+1);
            que.push(tmp.left);
        }
        if(tmp.right){
            LevMap.set(tmp.right,curlev+1);
            que.push(tmp.right);
        }
    }
    console.log(max);
}
//用节点记录当前层和下一层的终点,不用哈希表以减少空间复杂度
function GetWidth2(head){
    let que=new Array();
    que.push(head);
    let curend=head;let nextend=null;
    let max=-1;let cursum=0;
    while(que.length){
        let tmp=que.shift();
        cursum++;
        if(tmp.left){
            nextend=tmp.left;
            que.push(tmp.left);
        }
        if(tmp.right){
            nextend=tmp.right;
            que.push(tmp.right);
        }
        if(tmp==curend){
            curend=nextend;
            max=cursum>max?cursum:max;
            cursum=0;
        }
    }
    console.log(max);

}

//搜索二叉树判断 模板递归
function SearchTree(head){
    if(head==null){
        let tmp=new JST();
        tmp.isST=true;
        return tmp;
    }
    let left=new JST();
    left=SearchTree(head.left);
    let right=new JST();
    right=SearchTree(head.right);

    let sign=new JST();
    if(left.max!=null&&right.max!=null){//max不为空说明不为空树
        let ma=left.max>right.max?left.max:right.max;
        sign.max=head.value>ma?head.value:ma;
        let mi=left.min<right.min?left.min:right.min;
        sign.min=head.value<mi?head.value:mi;
    }
    else if(left.max!=null){
        sign.max=head.value>left.max?head.value:left.max;
        sign.min=head.value<left.min?head.value:left.min;
    }
    else{
        sign.max=head.value>right.max?head.value:right.max;
        sign.min=head.value<right.min?head.value:right.min;
    }
    sign.isST=true;
    if(left.isST==false||right.isST==false){
        sign.isST=false;
    }
    if(left.max!=null&&left.max>=head.value){
        sign.isST=false;
    }
    if(right.min!=null&&right.min<=head.value){
        sign.isST=false;
    }
    return sign;

}

//满二叉树 模板递归
function FullTree(head){
    if(head==null){
        let tmp=new JFT();
        tmp.isFT=true;tmp.height=0;tmp.nodeSum=0;
        return tmp;
    }
    let left=new JFT();
    let right=new JFT();
    left=FullTree(head.left);
    right=FullTree(head.right);

    let sign=new JFT();
    let ma=left.height>right.height?left.height:right.height;
    sign.height=ma+1;
    sign.nodeSum=left.nodeSum+right.nodeSum+1;
    sign.isFT=false;
    if(sign.nodeSum==Math.pow(2,sign.height)-1){
        sign.isFT=true;
    }
    return sign;

}

//平衡二叉树 模板递归
function SBTree(head){
    if(head==null){//设置baseCase
        let tmp=new JSBT();
        tmp.isSB=true;tmp.height=0;
        return tmp;
    }

    let left=new JSBT();//得到左右子树的返回
    let right=new JSBT();
    left=SBTree(head.left);
    right=SBTree(head.right);

    let sign=new JSBT();//给出自己的返回
    let ma=left.height>right.height?left.height:right.height;
    sign.height=ma+1;
    sign.isSB=true;
    if(left.isSB==false||right.isSB==false){
        sign.isSB=false;
    }
    if(Math.abs(left.height-right.height)>1){
        sign.isSB=false;
    }
    return sign;
}
//完全二叉树 BFS搞定
function CBT(head){
    let que=new Array();
    let isLeaf=false;
    let Ret=true;
    que.push(head);
    while(que.length){
        let tmp=que.shift();
        if(tmp.left==null&&tmp.right!=null){//任一节点有右无左false
            Ret=false;
            break;
        }
        if(isLeaf==false&&(tmp.left&&tmp.right==null)){//第一次遇到左右不全时,后续都是叶节点
            isLeaf=true;
        }
        else if(isLeaf&&(tmp.left||tmp.right)){//不是叶节点false
            Ret=false;
            break;
        }
        if(tmp.left){
            que.push(tmp.left);
        }
        if(tmp.right){
            que.push(tmp.right);
        }
    }
    console.log(Ret);
}

//找到最低公共祖先
//哈希表
function FindLA1(head,n1,n2){
    if(n1==n2){//假设给同一个节点
        return n1;
    }
    let fathetMap=new Map();
    let tmp=head;
    let stack=new Array();
    stack.unshift(head);
    fathetMap.set(head,head);//根的节点是他自己
    while(stack.length){//知道每一个节点的父亲节点
        tmp=stack.shift();
        if(tmp.left){
            fathetMap.set(tmp.left,tmp);
            stack.unshift(tmp.left);
        }
        if(tmp.right){
            fathetMap.set(tmp.right,tmp);
            stack.unshift(tmp.right);
        }
    }
    //从n1节点往上遍历,把他和他的父亲节点都放进set里
    let judgeSet=new Set();
    judgeSet.add(n1);
    tmp=n1;
    while(1){
        let tmpFather;
        tmpFather=fathetMap.get(tmp);
        judgeSet.add(tmpFather);
        if(tmp==tmpFather){//相等说明到根节点了
            break;
        }
        tmp=tmpFather;
    }
    //从n2节点往上遍历,从set里找第一个遇到的就是最低公共祖先
    tmp=n2;
    while(1){
        let tmpFather;
        tmpFather=fathetMap.get(tmp);
        if(judgeSet.has(tmpFather)){
            return tmpFather;
        }
        tmp=tmpFather;
    }

}
//奇妙的递归解决,相当于把n1,n2向上传递
function FindLA2(head,n1,n2){
    if(n1==n2){
        return n1;
    }
    if(head==null){
        return null;
    }
    let left=FindLA2(head.left,n1,n2);
    let right=FindLA2(head.right,n1,n2);

    if(head==n1||head==n2){
        return head;
    }
    if(left&&right){
        return head;
    }
    else if(left){
        return left;
    }
    else{
        return right;
    }
}
//找到后继节点 判断情况
function FindFollowNode(n1){
    if(n1.right){//n1有右树向下找最左节点
        let tmp=n1.right;
        while(tmp.left){
            tmp=tmp.left;
        }
        return tmp;
    }
    let father=n1.father;
    while(father){//n1无右树往上找,当前节点是其父节点的左孩子停,没找到也停
        if(father.left==n1){
            return father;
        }
        n1=father;
        father=n1.father;
    }   
    return null;
}
//先序遍历 序列化树,null值变为#
function Serial(head,arr){
    if(head==null){
        arr.push("#");
        return;
    }
    arr.push(head);
    Serial(head.left,arr);
    Serial(head.right,arr);
    return arr;
}
//先序遍历 反序列化
function DeSerial(head,arr){
    head=arr.shift();
    if(head=='#'){
        return null;
    }
    DeSerial(head.left,arr);
    DeSerial(head.right,arr);
    return head;
}
//折纸打印凹凸痕迹
function Aotu(num){
    printP(1,num,true);
}
function printP(i,num,flag){//i代表当前层数
    if(i>num){
        return;
    }
    printP(i+1,num,true);
    let tmp=flag==true?'凹':'凸';
    console.log(tmp);
    printP(i+1,num,false);
}
//测试用树 
let head2=new NodeS();
let ss1=new NodeS();
let ss2 =new NodeS();
let ss3 =new NodeS();
head2.value=1;head2.father=null;
ss1.value=2;ss2.value=3;ss3.value=4;
head2.left=ss1;ss1.father=head2;
head2.right=ss2;ss2.father=head2;
ss1.right=ss3;ss3.father=ss1;
//测试用树 普通
let head=new Node();
head.value=7;
let p1=new Node();
head.left=p1;p1.value=5;
let p2=new Node();
p1.left=p2;p2.value=3;
let p3=new Node();
p1.right=p3;p3.value=6;
let p4=new Node();
p3.left=p4;p4.value=9;
let p5=new Node();
p4.left=p5;p5.value=8;
let p6=new Node();
head.right=p6;p6.value=6;
let p7=new Node();
p6.left=p7;p7.value=1;
let p8=new Node();
p7.right=p8;p8.value=2;
let p9=new Node();
p8.left=p9;p9.value=11;
let p10=new Node();
p6.right=p10;p10.value=12;
// RePre(head);
// Pre(head);
// Post(head);
// Med(head);
// BFS(head);
// GetWidth(head);
// GetWidth2(head);

// let i=SearchTree(head);
// console.log(i.isST);
// i=SearchTree(head2);
// console.log(i.isST);

// let i=FullTree(head);
// console.log(i.isFT);
// i=FullTree(head2);
// console.log(i.isFT);

// let i=SBTree(head);
// console.log(i.isSB);
// i=SBTree(head2);
// console.log(i.isSB);

// CBT(head2);
// let tmp=FindLA2(head,p2,p10);
// console.log(tmp.value);

// let tmp=FindFollowNode(ss1);
// if(tmp)
// console.log(tmp.value);
// else
// console.log("null");
// let head3;
// let arr=new Array();
// arr=Serial(head,arr);
// head3=DeSerial(head3,arr);
// Post(head3);
// for(let i in arr){
//     console.log(arr[i]);
// }
Aotu(2);

 

posted @ 2022-04-04 15:07  ZZY22110  阅读(39)  评论(0)    收藏  举报