统计和生成所有不同的二叉树

#include "Tree.h"
using namespace std;
//实际上记录下从1到n的每个的可能的二叉树的个数
//num[i]表示有i个节点时,有多少可能的二叉树
//num[i + 1]可以由num[0]...num[i]的记录计算得到
//具体的计算方式是认为每个节点都可以做头结点,当节点j做头节点时
//可能的二叉树个数为左边的num[j - 1](j-1个节点的可能的二叉树个数)
//乘以右边的num[i - j](i-j个节点的可能的二叉树个数),num[j - 1]和num[i - j]
//一定能在保存好的记录num[0]...num[i]中找到
//最后累加得到num[i + 1]的值
int numTrees(int n)
{
    if(n < 2)
        return 1;
    int num[n + 1];
    num[0] = 1;
    for(int i = 1; i < n + 1; ++i)
    {
        for(int j = 1; j < i + 1; ++j)
            num[i] += num[j - 1] * num[i - j];
    }
    return num[n];
}
//返回N个节点可能的所有M个二叉树
Node* cloneTree(Node* head)
{
    if(head == nullptr)
        return nullptr;
    Node* res = new Node(head->value);
    res->left = cloneTree(head->left);
    res->right= cloneTree(head->right);
    return res;
}
list<Node*> genera(int start, int end)
{
    list<Node*> res;
    if(start > end)
        res.push_back(nullptr);
    Node* head = nullptr;
    for(int i = start; i < end + 1; ++i)
    {
        head = new Node(i);
        list<Node*> lSubs = genera(start, i - 1);
        list<Node*> rSubs = genera(i + 1, end);
        list<Node*>::iterator iterj;
        list<Node*>::iterator iterk;
        for(iterj = lSubs.begin(); iterj != lSubs.end(); ++iterj)
            for(iterk = rSubs.begin(); iterk != rSubs.end(); ++iterk)
        {
            head->left  = *iterj;
            head->right = *iterk;
            res.push_back(cloneTree(head));
        }
    }
    return res;
}
list<Node*> generateTree(int n)
{
    return genera(1, n);
}
int main()
{
    list<Node*> nList = generateTree(2);
    for(list<Node*>::iterator it = nList.begin(); it != nList.end(); ++it)
    {
        Print(*it);
        cout <<"================================="<< endl;
    }
}

猜你喜欢

转载自blog.csdn.net/wzc2608/article/details/80879904
今日推荐