顺序结构实现树,二叉树的重建

顺序结构实现树,二叉树的重建

二叉树的链式存储结构

struct Node
{
    bool have_value;
    int v;
    Node *left, *right;
    Node():have_value(false), left(NULL), right(NULL){}
};

二叉树的顺序存储结构

const int n = 10;
char data[n];
char lchild[n];
char rchild[n];
int bt;

表达式
( a + b ∗ ( c − d ) − e / f ) (a+b*(c-d)-e/f) (a+b(cd)e/f)
的二叉树,用顺序存储结构实现

#include <bits/stdc++.h>
using namespace std;

const int n = 11;

char data[n]=  {'-','+','/','a','*','e','f','b','-', 'c', 'd'};
int lch[n]={  1,  3,  5,  0,  7,  0,  0,  0,  9,   0,   0};
int rch[n]={  2,  4,  6,  0,  8,  0,  0,  0, 10,   0,   0};
int bt=0;

void perorder(int u)
{
    printf("%c ",data[u]);
    if(lch[u] == 0 && rch[u] == 0)
        return;
    if(lch[u])perorder(lch[u]);
    if(rch[u])perorder(rch[u]);
}

void inorder(int u)
{
    if(lch[u])inorder(lch[u]);
    printf("%c ",data[u]);
    if(rch[u])inorder(rch[u]);
    if(lch[u] == 0 && rch[u] == 0)
        return;
}

void postorder(int u)
{
    if(lch[u])postorder(lch[u]);
    if(rch[u])postorder(rch[u]);
    printf("%c ",data[u]);
    if(lch[u] == 0 && rch[u] == 0)
        return;
}

int main()
{

    printf("层序(不是真正的)遍历的结果是:\n");
    for(int i = 0; i < n; i++)
        printf("%c ", data[i]);

    printf("\n");
    printf("前序遍历的结果是:\n");
    perorder(bt);
    
    printf("\n");
    printf("中序遍历的结果是:\n");
    inorder(bt);

    printf("\n");
    printf("后序遍历的结果是:\n");
    postorder(bt);

    return 0;
}
层序(不是真正的)遍历的结果是:
- + / a * e f b - c d 
前序遍历的结果是:(前缀表示、波兰式)
- + a * b - c d / e f 
中序遍历的结果是:(中缀表示)
a + b * c - d - e / f 
后序遍历的结果是:(后缀表示,逆波兰式)
a b c d - * + e f / - 

二叉树的重建:中序+后序->前序

由中序和后序重建树,之后输出前序的结果,同时用dfs找到一个叶子使得它到根的路径上的权值和最小,这种重建树的方法,由于权重各不相同,所以以权值作为索引

#include <bits/stdc++.h>
using namespace std;
const int maxv = 10000 + 10;
int inorder[maxv];
int postorder[maxv];
int n;
int lch[maxv];
int rch[maxv];
bool read_list(int* a)
{
    string line;
    if(!getline(cin, line))return false;
    stringstream ss(line);
    n = 0;
    int x;
    while(ss >> x)a[n++] = x;
    return n>0;
}

int build(int L1, int R1, int L2, int R2)
{
    if(L1 > R1)return 0;
    int root = postorder[R2];
    //printf("root is %d\n",root);
    int p = L1;
    while(inorder[p] != root)p++;
    int cnt = p-L1;
    lch[root] = build(L1, p-1, L2, L2+cnt-1);
    rch[root] = build(p+1,R1, L2+cnt, R2-1);
    return root;
}

int best, best_sum=1000000000;

void dfs(int u, int sum)
{
    sum += u;
    if(lch[u] == 0 && rch[u] == 0)
    {
        if(sum < best_sum || (sum == best_sum && u < best))
        {
            best = u;
            best_sum = sum;
            printf("best is %d, best_sum is %d\n", best, best_sum);
        }
    }
    if(lch[u])dfs(lch[u], sum);
    if(rch[u])dfs(rch[u], sum);
}

void perorder(int u)
{
    printf("%d ",u);
    if(lch[u] == 0 && rch[u] == 0)
        return;
    if(lch[u])perorder(lch[u]);
    if(rch[u])perorder(rch[u]);
}

int main()
{
    // for(int i = 0; i < n; i++)
    // {
    //     cout << inorder[i] << " " << postorder[i] << endl;
    // }
    while(read_list(inorder))
    {
        read_list(postorder);
        // for(int i = 0; i < n; i++)
        // {
        //     cout << inorder[i] << " " << postorder[i] << endl;
        // }
        build(0, n-1, 0, n-1);
        for(int i = 0; i < 8; i++)
            printf("%d ", i);printf("\n");    
        
        printf("lch is:\n");
        for(int i = 0; i < 8; i++)
            printf("%d ", lch[i]);printf("\n");
            
        printf("rch is :\n");
        for(int i = 0; i < 8; i++)
            printf("%d ", rch[i]);printf("\n");

        printf("perorder is :\n");
        perorder(postorder[n-1]);
        printf("\n");

        printf("Minimum leaf :\n");
        dfs(postorder[n-1], 0);

        printf("best is %d\n", best);


    }
    return 0;
}
//输入
3 2 1 4 5 7 6
3 1 2 5 6 7 4
//输出
0 1 2 3 4 5 6 7 
lch is:
0 0 3 0 2 0 0 5 
rch is :
0 0 1 0 7 0 0 6 
perorder is :
4 2 3 1 7 5 6 
Minimum leaf :
best is 3, best_sum is 9
best is 1, best_sum is 7
best is 1

直接由前序+中序->后序

这里直接输出,没有重建树

其中特别需要注意的是,calc递归传进去的值,一定要考虑清楚,借用左子树的节点数这个变量,博主一开始就是有些小地方没注意到,错了,所以结果不对

#include <bits/stdc++.h>
using namespace std;

string s1, s2;

void calc(int l1, int r1, int l2, int r2)
{
	int m = s2.find(s1[l1]);
	//左子树的节点数
	int num = m-l2;
	//printf("%d\n", m);
	if(m > l2)calc(l1+1, l1+1+num-1, l2, m-1);
	if(m < r2)calc(l1+1+num-1+1, r1, m+1, r2);
	cout << s1[l1];
}

int main()
{
	cin >> s1 >> s2;
	//cout << s1 << " " << s2;
	calc(0, s1.length()-1, 0, s2.length()-1);
	return 0;
}
//输入
abdec
dbeac
//输出
debca

//输入
adbgcefh
dgbaechf
//输出
gbdehfca

//输入
ABDHIEJCFKG
HDIBEJAFKCG
//输出
HIDJEBKFGCA

直接由后序+中序->前序

由上边的例子修改的

#include <bits/stdc++.h>
using namespace std;

string s1, s2;

void calc(int l1, int r1, int l2, int r2)
{

	int m = s2.find(s1[r1]);
	//左子树的节点数
	int num = m-l2;
	cout << s1[r1];
	if(m > l2)calc(l1, l1+num-1, l2, m-1);
	if(m < r2)calc(l1+num, r1-1, m+1, r2);	
}

int main()
{
	cin >> s1 >> s2;
	//cout << s1 << " " << s2;
	calc(0, s1.length()-1, 0, s2.length()-1);
	return 0;
}
//输入
debca
dbeac
//输出
abdec

//输入
HIDJEBKFGCA
HDIBEJAFKCG
//输出
ABDHIEJCFKG

//输入
gbdehfca
dgbaechf
//输出
adbgcefh

前序+后序->中序

有多组解,此处不研究

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值