数据结构算法Day07

19、后序非递归遍历二叉树

void PostOrder(BiTree){
    BiTree p=T,r=NULL;//标记最近访问过的结点
    InitStack(S);
    while(p || !StackEmpty(S)){
        //一直向左访问
        if(p){
            push(S,p);
            p=p->lchild;
        }
        //左子树为空,判断是否存在右子树
        else{
            GetTop(S,p);
            if(p->rchild && p->rchild!=r){
                p=p->rchild;
                push(S,p);
            } 
            //指向右子树的左子树
            p=p->lchild;          
            else{
                //右子树也为空
                pop(S,p);
                visit(p);
                r=p;
                p=NULL;//结点访问完,重置p指针
            }
        }
    }
}
     

20、在二叉树中查找值为x的结点,打印出值为x的所有祖先

模板:

void func(BiTree T){
    if(T){
        (1)//操作一:当我们从上到下访问结点时需要做的操作
        func(T->lchild);
        (2)
        func(T->rchild);
        (3)//操作三:当我们从下往上时要做的操作
    }
}

因此,我们可以在操作一时让结点入栈,判断结点是否为x,如果是则直接打印栈中元素,否则继续运行下去,直到进行到操作三时让结点出栈

int i;
int top=0;
char path[100];
void allParent(BiTree T,char x){
    if(T){
        path[top]=T->data;
        top++;
        if(T->data==x){
            for(i=0;i<top;i++)
                std::cout<<path[i];
        }
        allParent(T->lchild,x);
        allParent(T->rchild,x);
        top--;
    }
}

21、层次遍历

利用队列,先让根入队,然后出队,访问出队结点,判断它是否存在左子树和右子树,如果有则让它们入队,接着依次进行下去,如此反复,直到队列为空

void levelOrder(BiTree T){
    InitQueue(Q);
    BiTree p;
    EnQueue(Q,T);
    while(!isEmpty(Q)){
        DeQueue(Q,p);
        visit(p->data);
        if(p->lchild)
            EnQueue(Q,p->lchild);
        if(p->rchild)
            Enqueue(Q,p->rchild);
    }

22、试给出自下而上、从右到左的层次遍历

恰好与上述层次遍历所求的队列相反,可以使用栈,再出队时先不访问该结点,而是将其压入栈中,最后弹栈访问结点。

void InverseLevel(BiTree T){
    if(T){
        InitStack(S);
        InitQueue(Q);
        BiTree p;
        EnQueue(Q,T);
        while(!isEmpty(Q)){
            DeQueue(Q,p);
            push(S,p);
            if(p->lchild)
                EnQueue(Q,p->lchild);
            if(p->rchild)
                EnQueue(Q,p->rchild);
        }
        while(!isEmpty(S)){
            Pop(S,p);
            visit(p->data);
        }
    }
}

23、求解二叉树的宽度

宽度:最大层结点总数

新定义一个队列,队列元素包含结点指针、以及层数。

typedef struct Qe{
    BiTree p;//节点信息
    int lv;//层数
}Qe;        
int Width(BiTree T){
    S Qu[30];
    int f,r,max;
    f=r=0;
    int level;
    BiTree q;
    if(T){
        //根节点入队列
        ++r;
        Qu[r].p=T;
        Qu[r].ln=1;
        //队不空,则进入循环
        while(f<r){
            //根节点出队列
            ++f;
            q=Qu[f].p;
            level=Qu[f].lv;
            if(q->lchild){
                ++r;
                Qu[r].p=q->lchild;
                Qu[r].lv=level+1;
            }
            if(q->rchild){
                ++r;
                Qu[r].p=q->rchild;
                Qu[r].lv=level+1;
            }
        }//层序遍历入队操作完
        max=0;
        for(int i=0;i<=level;i++){
            n=0;
              for(int j=0;j<=r;j++){
                if(Qu[j].lv==i)
                    n++;
              }
              if(n>max)
                    max=n;
        }//在队列中找层数一样的个数
        return max;
    }else
        return 0;
}

24、判断二叉树是否为完全二叉树

依旧是依靠层次遍历

bool Iscomple(BiTree T){
    InitQueue(Q);
    BiTree p;
    if(T){
        EnQueue(Q,T);
        while(!isEmpty(Q)){
            DeQueue(Q,p);//出队
            if(p){
                EnQueue(Q,p->lchild);
                Enqueue(Q,p->rchild);
            }else{
                while(!isEmpty(Q)){
                    DeQueue(Q,p);
                    if(p!=NULL)
                        return false;
                }
            }
        }
        return true;
    }else
        return false;
}
        

25、计算二叉树的带权路径长度(叶子节点)

int WPL(BiTree T){
    return wpl_preOder(T,0);
}
int wpl_preOrder(BiTree T,int deep){
    static int wpl=0;
    if(T){
        if(T->lchild==NULL&&T->rchild==NULL){
            wpl+=deep*T->weight;
        if(T->lchild)
            wpl_preOrder(T->lchild,deep+1);
        if(T->rchild)
            wpl_preOrder(T->rchild,deep+1);
    }
    return wpl;
}

26、将给定的二叉树转化为给定的中缀表达式

用中序遍历解决

void BTreetoE(BiTree T){
    BiTreeToExp(T,0);
}
void BiTreeToExp(BiTree T,int deep){
    if(T==NULL)
        return;
    else if(T->lchild==NULL&&T->rchild==NULL)
        printf("%s",T->data);
    else {
        if(deep>1)
            printf("(");
        BiTreeToExp(T->lchild,deep+1);
        printf("%s",T->data);
        BiTreeToExp(T->rchild,deep+1);
        if(deep>1)
            printf(")");
    }
}
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值