根结点到所有叶子结点的路径问题

这是一个典型的面试题。从网上查了很多代码,感觉部分写的不够严谨。今天做一个汇总。
思路:
1. 递归+回溯
2. 非递归的后序遍历(单栈版),每当遇到叶子结点,输出栈中元素即可。

以下代码都是基于思路一的代码。


版本一:引用vector

void LeavesPath(TreeNode* root, vector<int> &path){//引用vector
    if (root == NULL) return;
    path.push_back(root->val);
    if (root->left == NULL&&root->right == NULL){
        for (int i = 0; i < path.size(); i++){
            cout << path[i] << "  ";
        }
        cout << endl;
    }
    else
    {
        LeavesPath(root->left, path);
        LeavesPath(root->right, path);
    }
    path.pop_back();//关键
}

测试程序

        vector<int> path;
        LeavesPath(&n0, path);//n0为自己建造的树的根结点

版本二:数组+长度

void LeavesPath2(TreeNode* root, int* path,int len){
    if (root == NULL) return;
    path[len++] = root->val;
    if (root->left == NULL&&root->right == NULL){
        for (int i = 0; i < len; i++){
            cout << path[i] << "  ";
        }
        cout << endl;
    }
    else
    {
        LeavesPath2(root->left, path, len);
        LeavesPath2(root->right, path, len);
    }
}

测试程序

        int path2[20] = { 0 };
        LeavesPath2(&n0, path2, 0); //n0为自己建造的树的根结点

版本三:(引用)数组+引用长度

void LeavesPath3(TreeNode* root, int* &path, int& len){//int* &path替换成int*path也可以
    if (root == NULL) return;
    path[len++] = root->val;
    if (root->left == NULL&&root->right == NULL){
        for (int i = 0; i < len; i++){
            cout << path[i] << "  ";
        }
        cout << endl;
    }
    else
    {
        LeavesPath3(root->left, path, len);
        LeavesPath3(root->right, path, len);
    }
    --len;//这步操作与版本一中pop_back目的一样。
}

测试程序

        int path2[20] = { 0 };
        int len = 0;
        int *path3 = path2;
        LeavesPath3(&n0, path3, len);//n0为自己建造的树的根结点

结束语:

识别三个版本的差别,既能掌握递归的本质,又能体会到引用的作用。如果能试着把版本一转成非递归形式,那边又是一次提升。
个人推荐版本一,不知道你有什么看法。

你可能感兴趣的:(algorithm,二叉树,遍历,c-c++,叶子结点,路径)