树 2016.7.13

1、团队程序设计天梯赛-练习集-L2-006 树的遍历

解题思路:

利用后序遍历和中序遍历建树,再 bfs 求层级遍历

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 30 + 10;
int N;
int Post[maxn], In[maxn];

struct Tree {
    int Left, Right;
};

Tree tree[100000];

int Build(int Post_low, int Post_high, int In_low, int In_high);
void bfs(void);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    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]);
    }
    memset(tree, 0, sizeof(tree));
    Build(0, N, 0, N);
    bfs();
    return 0;
}

int Build(int Post_low, int Post_high, int In_low, int In_high)
{
    if (In_low+1 > In_high) {
        return 0;
    }
    int root = Post[Post_high-1];
    int Pos = In_low;
    while (In[Pos] != root) {
        ++Pos;
    }
    int Count = Pos - In_low;
    tree[root].Left = Build(Post_low, Post_low+Count, In_low, Pos);
    tree[root].Right = Build(Post_low+Count, Post_high-1, Pos+1, In_high);
    return root;
}

void bfs(void)
{
    queue<int> Queue;
    Queue.push(Post[N-1]);
    queue<int> ans;
    while (!Queue.empty()) {
        int t = Queue.front();
        if (t == 0) {
            break;
        }
        Queue.pop();
        ans.push(t);
        if (tree[t].Left != 0) {
            Queue.push(tree[t].Left);
        }
        if (tree[t].Right != 0) {
            Queue.push(tree[t].Right);
        }
    }
    printf("%d", ans.front());
    ans.pop();
    while (!ans.empty()) {
        printf(" %d", ans.front());
        ans.pop();
    }
    printf("\n");
}

2、团队程序设计天梯赛-练习集-L2-004 这是二叉搜索树吗?

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e3 + 10;
int BST[maxn];
int N;
int num = 0;

bool Text(int Left, int Right, bool Is_Mirror);
void Printf(int Left, int Right, bool Is_Mirror);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d", &N);
    for (int i = 0; i < N; ++i) {
        scanf("%d", &BST[i]);
    }
    if (Text(0, N, 0)) {
        printf("YES\n");
        Printf(0, N, 0);
        printf("\n");
    } else if (Text(0, N, 1)) {
        printf("YES\n");
        Printf(0, N, 1);
        printf("\n");
    } else {
        printf("NO\n");
    }
    return 0;
}

void Printf(int Left, int Right, bool Is_Mirror)
{
    if (Left+1 > Right) {
        return;
    }
    int root = BST[Left];
    int Count = Left+1;
    if (!Is_Mirror) {
        while (Count < Right && BST[Count] < root) {
            ++Count;
        }
    } else {
        while (Count < Right && BST[Count] >= root) {
            ++Count;
        }
    }
    Printf(Left+1, Count, Is_Mirror);
    Printf(Count, Right, Is_Mirror);
    printf(++num  == 1 ? "%d" : " %d", root);
}

bool Text(int Left, int Right, bool Is_Mirror)
{
    if (Left+1 >= Right) {
        return true;
    }
    int root = BST[Left];
    int Count = Left+1;
    int Mid = Count;
    if (!Is_Mirror) {
        while (Count < Right && BST[Count] < root) {
            ++Count;
        }
        Mid = Count;
        while (Count < Right && BST[Count] >= root) {
            ++Count;
        }
        if (Count != Right) {
            return false;
        }
    } else {
        while (Count < Right && BST[Count] >= root) {
            ++Count;
        }
        Mid = Count;
        while (Count < Right && BST[Count] < root) {
            ++Count;
        }
        if (Count != Right) {
            return false;
        }
    }
    return (Text(Left+1, Mid, Is_Mirror) && Text(Mid, Right, Is_Mirror));
}


3、团队程序设计天梯赛-练习集-L2-011 玩转二叉树

解题思路:

先利用中序遍历和前序遍历建镜像树,再 bfs 求层级遍历

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 30 + 10;

struct Tree {
    int Left, Right;
};

Tree tree[100000];

int N;
int Pre[maxn], In[maxn];

int Build(int Pre_low, int Pre_high, int In_low, int In_high);
void bfs(void);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d", &N);
    for (int i = 0; i < N; ++i) {
        scanf("%d", &In[i]);
    }
    for (int i = 0; i < N; ++i) {
        scanf("%d", &Pre[i]);
    }
    memset(tree, 0, sizeof(tree));
    Build(0, N, 0, N);
    bfs();
    return 0;
}

int Build(int Pre_low, int Pre_high, int In_low, int In_high)
{
    if (In_low+1 > In_high) {
        return 0;
    }
    int root = Pre[Pre_low];
    int Pos = In_low;
    while (In[Pos] != root) {
        ++Pos;
    }
    int Count = Pos-In_low;
    tree[root].Left = Build(Pre_low+1+Count, Pre_high, Pos+1, In_high);
    tree[root].Right = Build(Pre_low+1, Pre_low+1+Count, In_low, Pos);
    return root;
}

void bfs(void)
{
    queue<int> Queue;
    queue<int> ans;
    Queue.push(Pre[0]);
    while (!Queue.empty()) {
        int t = Queue.front();
        if (t == 0) {
            break;
        }
        Queue.pop();
        ans.push(t);
        if (tree[t].Left != 0) {
            Queue.push(tree[t].Left);
        }
        if (tree[t].Right != 0) {
            Queue.push(tree[t].Right);
        }
    }
    printf("%d", ans.front());
    ans.pop();
    while (!ans.empty()) {
        printf(" %d", ans.front());
        ans.pop();
    }
    printf("\n");
}

4、Vijos 1114 FBI树

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1100;
char s[maxn];
int num[maxn];
int N;

void dfs(int low, int high);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d%s", &N, s);
    int len = strlen(s);
    for (int i = 0; i < len; ++i) {
        num[i] = s[i] - '0';
    }
    dfs(0, len-1);
    printf("\n");
    return 0;
}

void dfs(int low, int high)
{
    if (low == high) {
        if (num[low] == 1) {
            printf("I");
        } else {
            printf("B");
        }
        return;
    }
    int mid = (low+high+1) >> 1;
    dfs(low, mid-1);
    dfs(mid, high);
    bool have_0 = false, have_1 = false;
    for (int i = low; i <= high; ++i) {
        if (num[i] == 1) {
            have_1 = true;
        } else {
            have_0 = true;
        }
        if (have_0 && have_1) {
            break;
        }
    }
    if (have_0 && have_1) {
        printf("F");
    } else if (have_0) {
        printf("B");
    } else {
        printf("I");
    }
}

5、二叉树的遍历问题

描述
输入一棵二叉树的先序和中序遍历序列,输出其后序遍历序列。
输入
输入共两行,第一行一个字符串,表示树的先序遍历,第二行一个字符串,表示树的中序遍历。树的结点一律用小写字母表示。
输出
输出仅一行,表示树的后序遍历序列。
样例输入
abdec
dbeac
样例输出
debca

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

#define DEBUG printf("DEBUG\n")

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
char Pre[maxn], In[maxn];

struct Tree {
    int Left, Right;
};

Tree tree[40];
int Pre_len, In_len;
bool vis[40];

int Build(int Pre_low, int Pre_high, int In_low, int In_high);
void Printf(int root);

int main()
{
#ifdef __AiR_H
    freopen("tree.in", "r", stdin);
    freopen("tree.out", "w", stdout);
#endif // __AiR_H
    scanf("%s%s", Pre, In);
    memset(tree, -1, sizeof(tree));
    memset(vis, false, sizeof(vis));
    Pre_len = strlen(Pre);
    In_len = strlen(In);

    Build(0, Pre_len, 0, In_len);
    Printf(Pre[0] - 'a');
    printf("\n");
    return 0;
}

int Build(int Pre_low, int Pre_high, int In_low, int In_high)
{
    if (In_low+1 > In_high) {
        return -1;
    }
    int root = Pre[Pre_low] - 'a';
    int Pos = In_low;
    while ((In[Pos]-'a') != root) {
        ++Pos;
    }
    int Count = Pos - In_low;
    tree[root].Left = Build(Pre_low+1, Pre_low+1+Count, In_low, Pos);
    tree[root].Right = Build(Pre_low+1+Count, Pre_high, Pos+1, In_high);
    return root;
}

void Printf(int root)
{
    if (root == -1) {
        return;
    }
    Printf(tree[root].Left);
    Printf(tree[root].Right);
    printf("%c", root+'a');
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值