zoukankan      html  css  js  c++  java
  • careercup-树与图 4.9

    4.9 给定一颗二叉树,其中每个结点都含有一个数值。设计一个算法,打印结点数值总和等于某个给定值的所有路径。注意,路径不一定非得从二叉树的根节点或叶子节点开始或结束。

    类似于leetcode:Path Sum II

    C++实现代码:(使用了双重的递归)对于不含有parent指针域时。

    #include<iostream>
    #include<new>
    #include<vector>
    using namespace std;
    
    //Definition for binary tree
    struct TreeNode
    {
        int val;
        TreeNode *left;
        TreeNode *right;
        TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    };
    
    class Solution
    {
    public:
        vector<vector<int> > path;
        vector<vector<int> > pathSum(TreeNode *root, int sum)
        {
            vector<int> tmp;
            hasPathSum(root,sum,tmp);
            //改变开始的节点,不一定要从根结点开始,遍历从每一个节点开始
            if(root->left)
                pathSum(root->left,sum);
            if(root->right)
                pathSum(root->right,sum);
            return path;
        }
        void hasPathSum(TreeNode *root, int sum,vector<int> tmp)
        {
            if(root==NULL)
                return;
            tmp.push_back(root->val);
            //改变结束的地方,不一定要到叶子节点
            if((sum-root->val)==0)
            {
                path.push_back(tmp);
            }
            if(root->left)
                hasPathSum(root->left,sum-root->val,tmp);
            if(root->right)
                hasPathSum(root->right,sum-root->val,tmp);
        }
        void createTree(TreeNode *&root)
        {
            int i;
            cin>>i;
            if(i!=0)
            {
                root=new TreeNode(i);
                if(root==NULL)
                    return;
                createTree(root->left);
                createTree(root->right);
            }
        }
    };
    int main()
    {
        Solution s;
        TreeNode *root;
        s.createTree(root);
        vector<vector<int> > path=s.pathSum(root,6);
        for(auto a:path)
        {
            for(auto v:a)
                cout<<v<<" ";
            cout<<endl;
        }
    }

     方法二:如果结点中包含指向父亲结点的指针,那么,只需要去遍历这棵二叉树, 然后从每个结点开始,不断地去累加上它父亲结点的值直到父亲结点为空(这个具有唯一性, 因为每个结点都只有一个父亲结点。也正因为这个唯一性, 可以不另外开额外的空间来保存路径),如果等于给定的值sum,则打印输出。

    实现的方法:

    void find_sum(Node* head, int sum){
        if(head == NULL) return;
        Node *no = head;
        int tmp = 0;
        for(int i=1; no!=NULL; ++i){
            tmp += no->key;
            if(tmp == sum)
                print(head, i);
            no = no->parent;
        }
        find_sum(head->lchild, sum);
        find_sum(head->rchild, sum);
    }

    打印输出时,只需要提供当前结点的指针,及累加的层数即可。然后从当前结点开始, 不断保存其父亲结点的值(包含当前结点)直到达到累加层数,然后逆序输出即可。

    代码如下:

    void print(Node* head, int level){
        vector<int> v;
        for(int i=0; i<level; ++i){
            v.push_back(head->key);
            head = head->parent;
        }
        while(!v.empty()){
            cout<<v.back()<<" ";
            v.pop_back();
        }
        cout<<endl;
    }

    方法三:如果结点中不包含指向父亲结点的指针,则在二叉树从上向下查找路径的过程中, 需要为每一次的路径保存中间结果,累加求和仍然是从下至上的,对应到保存路径的数组, 即是从数组的后面开始累加的,这样能保证遍历到每一条路径。

    代码如下:

    void print2(vector<int> v, int level){
        for(int i=level; i<v.size(); ++i)
            cout<<v.at(i)<<" ";
        cout<<endl;
    }
    void find_sum2(Node* head, int sum, vector<int> v, int level){
        if(head == NULL) return;
        v.push_back(head->key);
        int tmp = 0;
        for(int i=level; i>-1; --i){
            tmp += v.at(i);
            if(tmp == sum)
                print2(v, i);
        }
        vector<int> v1(v), v2(v);
        find_sum2(head->lchild, sum, v1, level+1);
        find_sum2(head->rchild, sum, v2, level+1);
    }

    方法二 完整代码:

    #include<iostream>
    #include<new>
    #include<map>
    #include<vector>
    using namespace std;
    
    struct BinarySearchTree
    {
        int elem;
        BinarySearchTree *parent;
        BinarySearchTree *left;
        BinarySearchTree *right;
        BinarySearchTree(int x):elem(x),parent(NULL),left(NULL),right(NULL) {}
    };
    
    void insert(BinarySearchTree *&root,int z)
    {
        BinarySearchTree *y=new BinarySearchTree(z);
        if(root==NULL)
        {
            root=y;
            return;
        }
        else if(root->left==NULL&&z<root->elem)
        {
            root->left=y;
            y->parent=root;
            return;
        }
        else if(root->right==NULL&&z>root->elem)
        {
            root->right=y;
            y->parent=root;
            return;
        }
        if(z<root->elem)
            insert(root->left,z);
        else
            insert(root->right,z);
    }
    
    void createBST(BinarySearchTree *&root)
    {
        int arr[10]= {10,4,6,1,8,3,0,7,2,9};
        for(auto a:arr)
            insert(root,a);
    }
    
    //使用level的原因就是因为,不一定要到根,只有根的父节点为NULL
    void print(BinarySearchTree *head,int level)
    {
        vector<int> vec;
        for(int i=0;i<level;++i)
        {
            vec.push_back(head->elem);
            head=head->parent;
        }
        while(!vec.empty())
        {
            cout<<vec.back()<<" ";
            vec.pop_back();
        }
        cout<<endl;
    }
    //root选择的是当前结束的节点,也就是从下往上开始最下面的节点,而node是往上找到的刚好满足的最后一个结点,root是在不断加深的
    void find_sum(BinarySearchTree *root,int sum)
    {
        if(root==NULL)
            return;
        BinarySearchTree *node=root;
        int tmp=0;
        for(int i=1;node!=NULL;++i)
        {
            tmp+=node->elem;
            if(tmp==sum)
                print(root,i);
            node=node->parent;
        }
        find_sum(root->left,sum);
        find_sum(root->right,sum);
    }
    int main()
    {
        BinarySearchTree *root=NULL;
        createBST(root);
        cout<<"find sum is: "<<endl;
        find_sum(root,10);
        return 0;
    }
    View Code

    方法三 完整代码:

    #include<iostream>
    #include<new>
    #include<map>
    #include<vector>
    using namespace std;
    
    struct BinarySearchTree
    {
        int elem;
        BinarySearchTree *parent;
        BinarySearchTree *left;
        BinarySearchTree *right;
        BinarySearchTree(int x):elem(x),parent(NULL),left(NULL),right(NULL) {}
    };
    
    void insert(BinarySearchTree *&root,int z)
    {
        BinarySearchTree *y=new BinarySearchTree(z);
        if(root==NULL)
        {
            root=y;
            return;
        }
        else if(root->left==NULL&&z<root->elem)
        {
            root->left=y;
            y->parent=root;
            return;
        }
        else if(root->right==NULL&&z>root->elem)
        {
            root->right=y;
            y->parent=root;
            return;
        }
        if(z<root->elem)
            insert(root->left,z);
        else
            insert(root->right,z);
    }
    
    void createBST(BinarySearchTree *&root)
    {
        int arr[10]= {10,4,6,1,8,3,0,7,2,9};
        for(auto a:arr)
            insert(root,a);
    }
    
    //使用level记录选择v中的从哪个下标开始相加
    void print(vector<int> v,int level)
    {
        for(int i=level;i<v.size();++i)
            cout<<v[i]<<" ";
        cout<<endl;
    }
    //root开始,将当前层的值加入v中
    void find_sum(BinarySearchTree *root,int sum,vector<int> v,int level)
    {
        if(root==NULL)
            return;
        v.push_back(root->elem);
        int tmp=0;
        for(int i=level;i>-1;--i)
        {
            tmp+=v[i];
            if(tmp==sum)
                print(v,i);
        }
        //每一层将当前层的结点的值放入v中,由于不是传递的引用,所以同一层放入v中的值不会影响,从root结点开始保存每一层的
        find_sum(root->left,sum,v,level+1);
        find_sum(root->right,sum,v,level+1);
    }
    int main()
    {
        BinarySearchTree *root=NULL;
        createBST(root);
        vector<int> v;
        cout<<"find sum is: "<<endl;
        find_sum(root,10,v,0);
        return 0;
    }
    View Code

  • 相关阅读:
    shl and shr
    清空和填充內存
    php 中instanceof的使用
    HTTP错误代码大全
    临时关闭Mysql ONLY_FULL_GROUP_BY
    php 中instanceof的使用
    Laravel Eloquent ORM 时如何查询表中指定的字段
    vagrant在windows下的使用
    下载配置python tornado web window7 开发笔记1:环境搭建
    运行确认怎么用vnc访问自己电脑,并且同时又是同一个会话?
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4148298.html
Copyright © 2011-2022 走看看