树 2016.8.23

1、二叉排序树

描述

依次给出n(0<n<=100000)个整数,请你以这n个数创建一棵二叉排序树,这棵排序树的根节点为第一个数,并输出其中序遍历和后序遍历。

输入
共两行,第一行为整数n,第二行为n个整数
输出
共两行,第一行为中序遍历,第二行为后序遍历
样例输入
8
23 45 12 6 7 89 13 47
样例输出
6 7 12 13 23 45 47 89 
7 6 13 12 47 89 45 23

#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 = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
int n;
int num[maxn];
int Count = 0;

struct BST {
    int key;
    BST* Left;
    BST* Right;
};

typedef BST *bst;

void Insert(bst root, int key);
void Printf(bst root);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d", &n);
    scanf("%d", &num[0]);
    bst root = (bst)malloc(sizeof(BST));
    root->key = num[0];
    root->Left = root->Right = NULL;
    for (int i = 1; i < n; ++i) {
        scanf("%d", &num[i]);
        Insert(root, num[i]);
    }
    sort(num, num+n);
    printf("%d", num[0]);
    for (int i = 1; i < n; ++i) {
        printf(" %d", num[i]);
    }
    printf("\n");
    Printf(root);
    printf("\n");
    return 0;
}

void Insert(bst root, int key)
{
    bst t = (bst)malloc(sizeof(BST));
    t->key = key;
    t->Left = t->Right = NULL;
    if (key < root->key) {
        if (root->Left == NULL) {
            root->Left = t;
            return;
        } else {
            Insert(root->Left, key);
        }
    } else {
        if (root->Right == NULL) {
            root->Right = t;
            return;
        } else {
            Insert(root->Right, key);
        }
    }
}

void Printf(bst root)
{
    if (root == NULL) {
        return;
    }
    Printf(root->Left);
    Printf(root->Right);
    printf(++Count == 1 ? "%d" : " %d", root->key);
}


2、打牌

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

#define REP(i, n) for (int i = 0; i < (n); ++i)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> SuperTree;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int num[maxn];
int N, M;
char cmd[10];
int cmd_num;
SuperTree Tree;
map<int, int> Map;

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    Map.clear();
    scanf("%d %d", &N, &M);
    for (int i = 0; i < N; ++i) {
        scanf("%d", &num[i]);
        Map[num[i]] = 1;
        Tree.insert(num[i]);
    }
    int Size = N;
    while (M--) {
        scanf("%s %d", cmd, &cmd_num);
        if (cmd[0] == 'i') {
            ++Size;
            Map[cmd_num] = 1;
            Tree.insert(cmd_num);
        } else if (cmd[0] == 'd') {
            if (Map[cmd_num] != 0) {
                --Size;
                Tree.erase(cmd_num);
                Map[cmd_num] = 0;
            } else {
                printf("invalid number!\n");
            }
        } else {
            if (cmd_num > Size) {
                printf("invalid K!\n");
            } else {
                printf("%d\n", *Tree.find_by_order(Size - cmd_num));
            }
        }
    }
    return 0;
}

3、UVa 548 Tree

题意:

给出中序遍历和后序遍历,输出最小路径的叶子结点


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

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e4 + 10;
int Count = 1;
int num[maxn * 2];

struct Tree {
    int Left, Right;
};

Tree tree[maxn];
int Min = INF;
int ans = 0;

int Build(int Post_low, int Post_high, int In_low, int In_high);
void dfs(int root, int sum);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    while (scanf("%d", &num[1]) == 1) {
        Count = 2;
        while (getchar() != '\n') {
            scanf("%d", &num[Count++]);
        }
        scanf("%d", &num[Count++]);
        while (getchar() != '\n') {
            scanf("%d", &num[Count++]);
        }
        Count -= 1;
        int nodes = Count / 2;
        int root = Build(nodes+1, Count, 1, nodes);
        Min = INF;
        dfs(root, root);
        printf("%d\n", ans);
    }
    return 0;
}

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

void dfs(int root, int sum)
{
    if (tree[root].Left == tree[root].Right && tree[root].Left == 0) {
        if (sum < Min) {
            Min = sum;
            ans = root;
        }
        return;
    }
    if (tree[root].Left != 0) {
        dfs(tree[root].Left, sum+tree[root].Left);
    }
    if (tree[root].Right != 0) {
        dfs(tree[root].Right, sum+tree[root].Right);
    }
}

4、UVa 10562  Undraw the Trees


注意:

①结点不一定是数字和字母

②当前行的字符串长度可能小于上一行

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

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 200 + 10;
char s[maxn][maxn];
int High = 1;
int len[maxn];

void dfs(int depth, int low, int high);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    int T;
    scanf("%d", &T);
    getchar();
    while (T--) {
        High = 0;
        memset(s, ' ', sizeof(s));
        while (gets(s[High]) && s[High][0] != '#') {
            len[High] = strlen(s[High]);
            ++High;
        }
        High -= 1;
        printf("(");
        dfs(0, 0, len[0]-1);
        printf(")\n");
    }
    return 0;
}

void dfs(int depth, int low, int high)
{
    if (depth > High) {
        return;
    }
    for (int i = low; i <= high; ++i) {
        if (i < len[depth] && s[depth][i] != '-' && s[depth][i] != '|' && s[depth][i] != ' ' && s[depth][i] != '#') {
            printf("%c", s[depth][i]);
            if (s[depth+1][i] == '|') {
                printf("(");
                int low = i, high = i;
                while (low-1 >= 0 && s[depth+2][low-1] == '-') {
                    --low;
                }
                while (s[depth+2][high+1] == '-') {
                    ++high;
                }
                dfs(depth+3, low, high);
                printf(")");
            } else {
                printf("()");
            }
        }
    }
}

5、HDU 3791 二叉搜索树

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

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 20;
char key[maxn], t[maxn];
int ans1[maxn], ans2[maxn];

struct BST {
    int Left, Right;
};

BST bst[maxn];

void Insert(int root, int x);
void bfs(int root, int num);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    int n;
    while (scanf("%d", &n) != EOF && n != 0) {
        memset(bst, -1, sizeof(bst));
        scanf("%s", key);
        int root = key[0] - '0';
        int len_key = strlen(key);
        for (int i = 1; i < len_key; ++i) {
            Insert(root, key[i] - '0');
        }
        bfs(root, 1);
        while (n--) {
            scanf("%s", t);
            bool flag = true;
            root = t[0] - '0';
            memset(bst, -1, sizeof(bst));
            for (int i = 1; i < len_key; ++i) {
                Insert(root, t[i] - '0');
            }
            bfs(root, 2);
            for (int i = 0; i < len_key; ++i) {
                if (ans1[i] != ans2[i]) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                printf("YES\n");
            } else {
                printf("NO\n");
            }
        }
    }
    return 0;
}

void Insert(int root, int x)
{
    if (x < root) {
        if (bst[root].Left == -1) {
            bst[root].Left = x;
            return;
        } else {
            Insert(bst[root].Left, x);
        }
    } else {
        if (bst[root].Right == -1) {
            bst[root].Right = x;
            return;
        } else {
            Insert(bst[root].Right, x);
        }
    }
}

void bfs(int root, int num)
{
    queue<int> Q;
    Q.push(root);
    int Count = 0;
    while (!Q.empty()) {
        int t = Q.front();
        Q.pop();
        (num == 1) ? ans1[Count++] = t : ans2[Count++] = t;
        if (bst[t].Left != -1) {
            Q.push(bst[t].Left);
        }
        if (bst[t].Right != -1) {
            Q.push(bst[t].Right);
        }
    }
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值