数据结构算法Day06

11、求二叉树中值为x的层号

int count=1;
void findLevel(BiTree T,int x){
    if(T==NULL)
        return;
    if(T->data==x){       
        printf("%d",count);
        return;
    }
    else{
        count++;
        findLevel(T->lchild,x);
        findLevel(T->rchild,x);
        count--;
    }
}

12、树中元素为x的结点,删除以它为根的子树

法一:递归法

//删除左子树,再删除右子树,最后删除根
void del_all(BiTree &T){
    del_all(T->lchild);
    del_all(T->rchild);
    free(T);
}
//先找到x
void DelTreeBynode(BiTree &T,int x){
    if(T==NULL)
        return;
    if(T->data==x){
        del_all(T);
        T=NULL;
        return;
    }
    DelTreeBynode(T->lchild,x);
    DelTreeBynode(T->rchild,x);
}

法二:层次法(这里依旧使用上面的del_all函数)

void DelTreeBynode(BiTree &T,int x){
    Sq Q;//定义一个队列
    BiTree p=NULL;
    InitQueue(Q);//初始化队列
    if(T){
        //T的data刚好是x
        if(T->data==x){
            del_all(T);
            exit(0);//直接结束进程
        }
        //否则
        //让其进入队列
        EnQueue(Q,T);
        While(!isEmpty(Q)){//只要Q不为空
            DeQueue(Q,p);
            //判断p的左子树
            if(p->lchild){
                if(p->lchild->data==x){
                    del_all(P->lchild);
                    p->lchild=NULL;
                }else
                    EnQueue(Q,p->lchild);
            }
            //判断p的右子树
            if(p->rchild){
                if(p->rchild->data==x){
                    del_all(p->rchild);
                    p->rchild=NULL;
                }else
                    EnQueue(Q,p->rchild);
            }
        }
    }
}
 

13、利用结点的右孩子指针将一个二叉树的叶子节点从左向右连接成一个单链表(head指向第一个,tail指向最后一个)

这里采用中序遍历的思想

LinkList head,tail=NULL;
void connLeaf(BiTree T){
    if(T){
        connLeaf(T->lchild);
        if(T->lchild==NULL&&T->rchild==NULL){
            //第一个结点
            if(tail==NULL){
                head=T;
                tail=T;
            }
            else{
                tail->next=T;
                tail=T;
            }
        }
        connLeaf(T->rchild);
        tail->next=NULL;
    }
    return head;
}

14、输出根节点到每个叶子结点的路径

1、这里采用先序遍历

2、对特殊的结点(叶子结点)进行处理

3、利用栈

int i=0,top=0;
ElemType Stack[MaxSize];
void leafPath(BiTree T){
    if(T){
        Stack[top]=T->data;
        ++top;
        if(T->lchild==NULL&&T->rchild==NULL){
            for(i=0;i<top;i++)
                printf("%c",Stack[i]);
        }
        leafPath(T->lchild);
        leafPath(T->rchild);
        --top;
    }
    return;
}
        

15、已知满二叉树先序序列存在数组中,设计算法将其变成后序序列

对于整个序列来说,先序序列的第一个结点就是后序序列的最后一个结点,本题是满二叉树,左右子树都含有相同数目的结点,所以左右子树分别也有这样的性质,采用递归交换先序序列第一个结点与最后一个一个结点。(关键是找位置!)

//l1为先序第一个值位置,h1为先序的最后一个位置
//l2为后序第一个值位置,h2为后序的最后一个位置
void PreToPost(ElemType Pre[],int l1,int h1,ElemType Post[],int l2,int h2){
    int half;
    if(l1<=h1){
        Post[l2]=Pre[l1];
        half=(h1-l1)/2;
        //处理左子树
        PreToPost(Pre,l1+1,l1+half,Post,l2,l2+half-1);
        //处理右子树
        PreToPost(Pre,l1+half+1,h1,Post,l2+half,h2-1);
    }
}

16、先序和中序遍历分别存在两个一维数组A,B中,试着建立二叉链表

1、根据先序序列确定树的根节点

2、找出划分左右二叉树的位置

3、再进行找根节点

BiTree PreInCreat(ElemType A[],ElemType B[],int l1,int h1,int l2,int h2){
    BiTNode* root=(BiTNode*)malloc(sizeof(BiTNode));
    root->data=A[l1];
    for(i=l2;B[i]!=root->data;i++);
    llen=i-l2;//左子树长度
    rlen=h2-i; //右子树长度
    if(llen)
        PreInCreat(A,B,l1+1,l1+llen,l2,l2+llen-1);
    else 
        root->lchild=NULL;
    if(rlen)
        PreInCreat(A,B,h1-rlen+1,h1,h2-rlen+1,h2);
    else
        root->rchild==NULL;
    return root;
}

17、中序非递归遍历二叉树

入栈向左一直走,出栈访问右子树

void InOrder(BiTree T){
    InitStack(S);
    BiTree p=T;
    while(p || !StackEmpty(S)){
        if(p){
            push(S,p);
            p=p->lchild;
        }
        else{
            pop(S,p);
            visit(p);
            p=p->rchild;
        }
    }
}  

18、中序非递归遍历二叉树

访问入栈一直向左走,出栈右子树

void PreOrder(BiTree T){
     InitStack(S);
     BiTree p=T;
     while(p || !StackEmpty(S)){
        if(p){
            visit(p);
            push(S,p);
            p=p->lchild;
        }
        else{
            pop(S,p);
            p=p->rchild;
        }
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值