zoukankan      html  css  js  c++  java
  • 备战快速复习--day5

    树的遍历,在构造树的过程中,多个孩子用vector来表示,有的时候孩子需要排序

    PAT A1053

    dfs有权树然后输出路径权值和目标相同的,必须走到叶子节点。另外要求输出按照非降序输出(这个非降序,仅考虑A>B 在min(lena,lenb)中,第一个不等的是A[i]>B[I]),不考虑长度不同。

    解题思路

    这个就是正常dfs,存储当前节点和遍历情况,注意在dfs中,保存遍历的判定条件需要在dfs结束当前轮的时候修改,但是保存结果的不用修改,自动顶掉了。

    还有cmp数组,这个序号是已知的,只需要对里面的孩子节点进行一下排序,并且只需要考虑大小,因为认为3 2 3 和3 2 3 4也算非降序。

    #include<stdio.h>
    #include<iostream>
    #include<vector>
    #include<algorithm>
    #define maxn 100
    using namespace std;
    int n,nonleafnum,target;
    int ansroute[105];
    using namespace std;
    struct node{
        int w;
        vector<int>child;
    }Node[maxn];
    bool cmp(int a,int b)
    {
        return Node[a].w>Node[b].w;
    }
    void dfs(int nodenum,int sum,int num)//当前节点编号,目前总价,这是第几个节点
    {
        if(target==sum+Node[nodenum].w && Node[nodenum].child.size()==0)
        {
            ansroute[num]=nodenum;
            for(int i=0;i<=num-1;i++)
            {
                printf("%d ",Node[ansroute[i]].w);
            }
            printf("%d
    ",Node[ansroute[num]].w);
            return ;
        }
        if(Node[nodenum].child.size()==0||(sum+Node[nodenum].w>=target))
            return ;
        ansroute[num]=nodenum;
        sum=sum+Node[nodenum].w;
        for(int i=0;i<Node[nodenum].child.size();i++)
        {
            dfs(Node[nodenum].child[i],sum,num+1);
        }
    }
    int main()
    {
        scanf("%d %d %d",&n,&nonleafnum,&target);
        for(int i=0;i<=n-1;i++)
        {
            int tempw;
            scanf("%d",&tempw);
            Node[i].child.clear();
            Node[i].w=tempw;
        }
        for(int i=1;i<=nonleafnum;i++)
        {
            int temp,tempnum,tempchild;
            scanf("%d%d",&temp,&tempnum);
            for(int j=1;j<=tempnum;j++)
            {
                scanf("%d",&tempchild);
                Node[temp].child.push_back(tempchild);
            }
            sort(Node[temp].child.begin(),Node[temp].child.end(),cmp);
        }
        dfs(0,0,0);//当前坐标,当前已有w数值,
        return 0;
    }
    View Code

     借着这个输入格式实现了一下先根遍历和层次遍历。这个因为存在vector.size(),就不用NULL了,原理都差不多。

    (先根遍历,是先走根节点,本质跟dfs一样,层次是bfs)

    #include<stdio.h>
    #include<iostream>
    #include<vector>
    #include<algorithm>
    #define maxn 100
    #include<queue>
    using namespace std;
    int n,nonleafnum,target;
    int ansroute[105];
    using namespace std;
    struct node{
        int w;
        vector<int>child;
    }Node[maxn];
    bool cmp(int a,int b)
    {
        return Node[a].w>Node[b].w;
    }
    void preOrder(int root)
    {
        printf("%d ",Node[root].w);
        for(int i=0;i<Node[root].child.size();i++)
            preOrder(Node[root].child[i]);
    }
    void layerOrder(int root)
    {
        queue<int>q;
        q.push(root);
        while(!q.empty())
        {
            int temp=q.front();
            q.pop();
            printf("%d ",Node[temp].w);
            for(int i=0;i<Node[temp].child.size();i++)
            {
                q.push(Node[temp].child[i]);
            }
        }
    }
    int main()
    {
        scanf("%d %d %d",&n,&nonleafnum,&target);
        for(int i=0;i<=n-1;i++)
        {
            int tempw;
            scanf("%d",&tempw);
            Node[i].child.clear();
            Node[i].w=tempw;
        }
        for(int i=1;i<=nonleafnum;i++)
        {
            int temp,tempnum,tempchild;
            scanf("%d%d",&temp,&tempnum);
            for(int j=1;j<=tempnum;j++)
            {
                scanf("%d",&tempchild);
                Node[temp].child.push_back(tempchild);
            }
        }
        preOrder(0);
        printf("
    ");
        layerOrder(0);
        return 0;
    }
    View Code

     二叉搜索树

    这个就是左子树里面的点都小于右子树里面的点。唯一需要注意的就是删除的时候不能直接让root等于其他的节点,因为还有别的指针关系,在root不是NULL的时候修改root的值,根据左右子树是否为空的情况选中前驱或者后驱。选前后驱时候里面的参数是左右子节点的指针哦。然后删除对应前后驱的时候记得用delete,因为他们可能还有子节点,直接释放是不可以的。部分代码如下(这里面的insert有重复的数就不插入了,实际题目一般不是这种,审题)

    这里面有一部分常见操作:findMax是前驱,找左子树里面最大的。这里面insert和delete是引用node*&root

    #include<stdio.h>
    #include<iostream>
    #include<queue>
    using namespace std;
    struct node
    {
        int data;
        node*lchild;
        node*rchild;
    };
    node*newNode(int x)
    {
        node*temp=new node;
        temp->data=x;
        temp->lchild=NULL;
        temp->rchild=NULL;
    }
    void search(node*root,int x)
    {
        if(root==NULL)
        {
            printf("search failed
    ");
            return ;
        }
        if(x==root->data)
        {
            printf("%d
    ",root->data);
        }
        else if(x<root->data)
        {
            search(root->lchild,x);
        }
        else
            search(root->rchild,x);
    }
    void insert(node*&root,int x)
    {
        if(root==NULL)
        {
            root=newNode(x);
            return ;
        }
        if(root->data==x)
            return;
        else if(x<root->data)
        {
            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;
    }
    node*findMax(node*root)
    {
        while(root->rchild!=NULL)
            root=root->rchild;
        return root;
    }
    node*findMin(node*root)
    {
        while(root->lchild!=NULL)
            root=root->lchild;
        return root;
    }
    void deleteNode(node*&root,int x)
    {
        if(root==NULL) return;
        if(root->data==x)
        {
            if(root->lchlid==NULL && root->rchild==NULL)
                root=NULL;
            else if(root->lchild!=NULL)
            {
                node*temp=findMax(root->lchild);
                root->data=temp->data;
                delete(root->lchild,temp->data);
            }
            else
            {
                node*temp=findMin(root->rchild);
                root->data=temp->data;
                delete(root->rchild,temp->data);
            }
        }
        else if(root->data>x)
            deleteNode(root->lchild,x);
        else
            deleteNode(root->rchild,x);
    }
    View Code

    PAT A1043

    这个是给一组数构造二叉搜索树,判断构造出来的前序是否和这个相同,如果相同输出后序。如果跟镜像相同,输出镜像树的后序,他们不是直接倒着输出数组的关系哦,最好还是自己写函数,简单调整一下递归顺序就行。

    另外需要注意的点:最后一个不能有空格,那么就必须存储结果之后统一输出。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    using namespace std;
    struct node{
        int data;
        node*lchild;
        node*rchild;
    };
    int n;
    int a[1000];
    int ans[1000];
    int ans2[1000];
    int count=0;
    int count2=0;
    node*newNode(int x)
    {
        node*temp=new node;
        temp->data=x;
        temp->lchild=NULL;
        temp->rchild=NULL;
        return temp;
    }
    void insert(node*&root,int x)
    {
        if(root==NULL)
        {
            root=newNode(x);
            return;
        }
        if(x<root->data)
            insert(root->lchild,x);
        else
            insert(root->rchild,x);
    }
    void preOrder(node*root)
    {
        if(root==NULL)
            return;
        //printf("%d",root->data);
        ans[count++]=root->data;
        preOrder(root->lchild);
        preOrder(root->rchild);
    }
    void mirrorOrder(node*root)
    {
        if(root==NULL)
            return ;
        ans2[count2++]=root->data;
        mirrorOrder(root->rchild);
        mirrorOrder(root->lchild);
    }
    void postOrder(node*root)
    {
        if(root==NULL)
            return ;
        postOrder(root->lchild);
        postOrder(root->rchild);
        //printf("%d ",root->data);
        ans[count++]=root->data;
    }
    void mirrorPost(node*root)
    {
        if(root==NULL)
            return;
        mirrorPost(root->rchild);
        mirrorPost(root->lchild);
        //printf("%d ",root->data);
        ans2[count2++]=root->data;
    }
    int main()
    {
        node*root=new node;
        root=NULL;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            insert(root,a[i]);
        }
        preOrder(root);
        mirrorOrder(root);
        bool pd1=true;
        bool pd2=true;
        for(int i=0;i<n;i++)
        {
            //printf("%d",ans[i]);
            if(ans[i]!=a[i])
                pd1=false;
            if(ans2[i]!=a[i])
                pd2=false;
        }
        if(pd1)
        {
            count=0;
            printf("YES
    ");
            postOrder(root);
            for(int i=0;i<=n-2;i++)
                printf("%d ",ans[i]);
            printf("%d",ans[n-1]);
        }
        else if(pd2)
        {
            count2=0;
            printf("YES
    ");
            mirrorPost(root);
            for(int i=0;i<=n-2;i++)
                printf("%d ",ans2[i]);
            printf("%d",ans2[n-1]);
        }
        else
            printf("NO
    ");
        return 0;
    }
    View Code
    时间才能证明一切,选好了就尽力去做吧!
  • 相关阅读:
    Base64简介
    grafana+graphit安装笔记
    朋友圈里的格局
    设计模式值六大原则——接口隔离原则 (ISP)
    设计模式值六大原则——迪米特法则(LoD)也称为最少知识原则(LKP)。
    设计模式值六大原则——开闭原则(OCP)
    设计模式值六大原则——里氏替换原则(LSP)
    工厂模式
    JSON简介以及用法代码汇总
    sql where 1=1和 0=1 的作用
  • 原文地址:https://www.cnblogs.com/tingxilin/p/12340995.html
Copyright © 2011-2022 走看看