• 备战快速复习--day4


    二叉树,可以用指针来存也可以用数组来存,使用数组的时候应该是完全二叉树。

    在数组存储的方式中(认为根节点是1),当前节点是x,左子孩子是2*x,到第n层有2^n-1个节点。要判断为空,就是下标大于节点总个数,判断有无子树就用2*x和n判断。

    在指针存储的时候,记得初始化root为node*root=NULL,所有的新节点左右子树都是NULL

    root=NULL,root->lchild=NULL,root->rchild=NULL,代表的是他们没有指向。

    定义的时候是指针,在修改其指向的内容的时候正常修改就行(一直指向A,A里面元素被改了),如果修改其内容(就是修改指针指向的对象,由指向A变成指向B)要使用引用

    里面的change(node*&root),要这种格式,别忘了还是指针,要有*,在调用的时候直接change(root)就可以。

    #include<stdio.h>
    struct node{
        int data;
        node*lchild;
        node*rchild;
    };
    node*root=NULL;//建树之前不存在,初始为空
    node*newNode(int v)
    {
        node*Node=new node;
        Node->data=v;
        Node->lchild=NULL;
        Node->rchild=NULL;
        return Node;
    }//新建节点
    void search(node*root,int x,int newdata)
    {
        if(root==NULL)
            return ;
        if(root->data==x)
            root->data=newdata;
        search(root->lchild,x,newdata);
        search(root->rchild,x,newdata);
    }
    void insert(node*&root,int x)
    {
        if(root==NULL)
        {
            root=newNode(x);
            return;
        }
        if(root->data==1)//什么条件在左子树插入
            insert(root->lchild,x);
        else
            insert(root->rchild,x);
    }
    node*Create(int data[],int n)
    {
        node*root=NULL;
        for(int i=0;i<n;i++)
            insert(root,data[i]);
        return root;
    }
    View Code

    指针中几个常用的操作代码如上。

    先中后序还有层次遍历递归实现代码如下

    #include<stdio.h>
    #include<queue>
    using namespace std;
    struct node{
        int data;
        node*lchild;
        node*rchild;
    };
    node*newNode(int v)
    {
        node*Node=new node;
        Node->data=v;
        Node->lchild=NULL;
        Node->rchild=NULL;
        return Node;
    }
    void preOrder(node*root)
    {
        if(root==NULL)
            return;
        printf("%d",root->data);
        preOrder(root->lchild);
        preOrder(root->rchild);
    }
    void inOrder(node*root)
    {
        if(root==NULL)
            return;
        inOrder(root->lchild);
        printf("%d",root->data);
        inOrder(root->rchild);
    }
    void postOrder(node*root)
    {
        if(root==NULL)
            return;
        postOrder(root->lchild);
        postOrder(root->rchild);
        printf("%d",root->data);
    }
    void LayerOrder(node*root)
    {
        queue<node*>q;
        q.push(root);
        node*temp=q.front();
        while(!q.empty())
        {
            node*temp=q.front();
            q.pop();
            if(temp->lchild!=NULL)
                q.push(temp->lchild);
            if(temp->rchild!=NULL)
                q.push(temp->rchild);
            printf("%d",temp->data);
        }
    }
    int main()
    {
        node *root=newNode(1);
        root->lchild=newNode(2);
        root->rchild=newNode(3);
        root->lchild->lchild=newNode(4);
        root->lchild->rchild=newNode(5);
        root->rchild->rchild=newNode(6);
        preOrder(root);
        printf("
    ");
        inOrder(root);
        printf("
    ");
        postOrder(root);
        printf("
    ");
        LayerOrder(root);
        printf("
    ");
        return 0;
    }
    View Code

    注意,给定中序遍历和先后层次中任意一个,可以确定二叉树,给后面中的两个是不能确定的。中序用于确定左右子树,后面三个任一个都可以确定根节点。

    这里面的生成条件,需要子树里面的data没有重复的元素。

    PAT A1020给定后序中序生成二叉树,并以层次遍历输出

    这个需要注意,要求结尾没有多余空格,加个判断就行。

    具体思路就是,每次最尾的是根节点,根节点在中序中判断左右子树以后,求出左右子树的节点数目,再划分出后序里面哪些属于左右,前转中同理。

    #include<stdio.h>
    #include<iostream>
    #include<queue>
    using namespace std;
    int n;
    int in[35];
    int post[35];
    struct node
    {
        int data;
        node*lchild;
        node*rchild;
    };
    void level(node*root)
    {
        queue<node*>q;
        q.push(root);
        while(!q.empty())
        {
            node*temp=q.front();
            q.pop();
            if(temp->lchild!=NULL)
                q.push(temp->lchild);
            if(temp->rchild!=NULL)
                q.push(temp->rchild);
            if(!q.empty())
                printf("%d ",temp->data);
            else
                printf("%d",temp->data);
        }
    }
    node* change(int inl1,int inr1,int post1,int post2)
    {
        if(inl1>inr1) return NULL;
        node*root=new node;
        root->data=post[post2];
        //printf("here:%d
    ",root->data);
        int temp=-1;
        for(int i=inl1;i<=inr1;i++)
        {
            if(in[i]==post[post2])
            {
                temp=i;
                break;
            }
        }
        if(temp!=-1)
        {
            root->lchild=change(inl1,temp-1,post1,post1+temp-inl1-1);
            root->rchild=change(temp+1,inr1,post1+temp-inl1,post2-1);
        }
        return root;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&post[i]);
        for(int i=0;i<n;i++)
            scanf("%d",&in[i]);
        level(change(0,n-1,0,n-1));
        return 0;
    }
    View Code

    如果题目考察层次遍历和中序,那么是选中根节点,划分左右子树以后,使用vector,然后判断中序中左右出现的节点和层次中相同,(根据其在层次遍历中的顺序)加入左或者右对应的数组,再进行下一轮递归。

    时间才能证明一切,选好了就尽力去做吧!
  • 相关阅读:
    【Jenkins】jenkins 配置腾讯企业邮箱
    Monkey 用户指南(译)
    Windows,easygui 安装
    python笔记:list--pop与remove的区别
    递归--Java_汉诺塔
    appium安装 For windows
    【web开发--js学习】functionName 如果是一个属性值,函数将不会被调用
    python爬取煎蛋网图片
    pv&pvc
    docker
  • 原文地址:https://www.cnblogs.com/tingxilin/p/12335363.html
Copyright © 2020-2023  润新知