数据结构-构建二叉树

用先序序列和中序序列构建二叉树,采用二叉链表存储。编写递归算法,交换二叉树的左右子树,
输出新二叉树按先序遍历得到的结果。

提交格式:实现void solve(int n, int *preOrder, int *inOrder, int *outOrder)函数。
函数参数为序列长度n、先序序列preOrder、中序序列inOrder和输出序列outOrder。1<=n<=1000000,树的深度<=2000。
请不要printf输出任何内容。

输入样例1:
n=5,preOrder={1,2,3,4,5},inOrder={3,2,4,1,5}
输出样例1:
outOrder={1,5,2,4,3}

可以使用以下代码来实现递归交换二叉树左右子树的算法:

#include <iostream>
#include <vector>

using namespace std;

struct TreeNode {
  int val;
  TreeNode *left;
  TreeNode *right;
  TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

// 通过先序遍历和中序遍历构建二叉树
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
  if (preorder.empty()) return NULL;

  int root_val = preorder[0];
  TreeNode* root = new TreeNode(root_val);

  int k = 0;
  // 找到根节点在中序遍历中的位置
  while (inorder[k] != root_val) ++k;

  vector<int> left_preorder(preorder.begin() + 1, preorder.begin() + 1 + k);
  vector<int> left_inorder(inorder.begin(), inorder.begin() + k);
  root->left = buildTree(left_preorder, left_inorder);

  vector<int> right_preorder(preorder.begin() + 1 + k, preorder.end());
  vector<int> right_inorder(inorder.begin() + k + 1, inorder.end());
  root->right = buildTree(right_preorder, right_inorder);

  return root;
}

// 递归交换二叉树的左右子树
void swapSubtrees(TreeNode* root) {
  if (root == NULL) return;
  swap(root->left, root->right);
  swapSubtrees(root->left);
  swapSubtrees(root->right);
}

// 先序遍历二叉树,将遍历结果存入数组中
void preOrderTraverse(TreeNode* root, vector<int>& outOrder) {
  if (root == NULL) return;
  outOrder.push_back(root->val);
  preOrderTraverse(root->left, outOrder);
  preOrderTraverse(root->right, outOrder);
}

void solve(int n, int* preOrder, int* inOrder, int* outOrder) {
  // 将先序遍历和中序遍历的数组转为 vector
  vector<int> preorder(preOrder, preOrder + n);
  vector<int> inorder(inOrder, inOrder + n);

  // 通过先序遍历和中序遍历构建二叉树
TreeNode* root = buildTree(preorder, inorder);
// 递归交换二叉树的左右子树
swapSubtrees(root);
// 先序遍历二叉树,将遍历结果存入数组中
vector<int> outorder;
preOrderTraverse(root, outorder);

// 将 vector 转为数组
copy(outorder.begin(), outorder.end(), outOrder);
}

在函数 solve 中,首先将先序遍历和中序遍历的数组转为 vector,然后调用函数 buildTree 来构建二叉树。然后调用函数 swapSubtrees 来递归交换二叉树的左右子树,最后调用函数 preOrderTraverse 对二叉树进行先序遍历,将遍历结果存入数组中。


#include <iostream>
using namespace std;
typedef struct BiNode
{
    char date; //二叉链表的定义
    struct BiNode *lchild, *rchild;
} BiTNode, *BiTree;

//用先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T) //&引用
{
    //按照先序次序输入二叉树中节点的值(一个字符),创建二叉链表表示的二叉树T;
    char ch;
    cin >> ch;
    if (ch == '#')
        T = NULL;
    else
    {
        T = new BiTNode;         // 分配空间
        T->date = ch;            // 生成根节点
        CreateBiTree(T->lchild); //递归创建左子数
        CreateBiTree(T->rchild); //递归创建右子树
    }
}
//中序遍历二叉树T的递归算法 左根右,如果想搞清楚无比要懂得如何递归且根据图来画一画。
void InOrderTraverse(BiTree T)
{
    if (T)
    {
        InOrderTraverse(T->lchild);
        cout << T->date;
        InOrderTraverse(T->rchild);
    }
}
int main()
{
    BiTree tree;
    cout << "请输入二叉链表的序列: \n";
    CreateBiTree(tree);
    cout << "遍历结果为:\n";
    InOrderTraverse(tree);

}


#include<iostream>

using namespace std;
#define OK 1
#define ERROR 0
#define FALSE -1
#define OVERFLOW -2

typedef char TElemType;
typedef int Status;

typedef struct BiTNode {
    TElemType data;
    struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;


//初始化
Status InitBiTree(BiTree T) {
    if (!(T = new BiTNode)) return ERROR;
    T->lchild = NULL;
    T->rchild = NULL;
    return OK;
}

Status DestoryBiTree(BiTree& T) {
    if (!T) return FALSE;
    else {
        if (T->lchild != NULL)
            DestoryBiTree(T->lchild);
        if (T->rchild != NULL)
            DestoryBiTree(T->rchild);

        delete T;
        return OK;
    }
}


BiTree Root(BiTree T) {
    if (T == NULL) return NULL;
    return T;
}


Status ClearBiTree(BiTree T) {
    BiTNode* p;
    p = T;
    if (p) {
        DestoryBiTree(p);
        T->lchild = NULL;
        T->rchild = NULL;
        return OK;
    }
}

//用前序遍历的递归方式实现深度优先搜索
void PreOrderTraverse(BiTree T) {
    //T为树根的指针
    //如果T非空
    if (T) {
        //输出T结点的值
        cout << T->data << " ";
        //遍历左子树
        PreOrderTraverse(T->lchild);
        //遍历右子树
        PreOrderTraverse(T->rchild);
    }
    else return;
}

//创建二叉树
Status CreatBiTree(BiTree& T) {

    char ch;
    cin >> ch;
    if (ch == '#') T = NULL;//#代表二叉树为空树
    else {
        if (!(T = new BiTNode))
            exit(OVERFLOW);
        T->data = ch;//生成根节点
        CreatBiTree(T->lchild);//递归创建左子树
        CreatBiTree(T->rchild);//递归创建右子树
    }
    return OK;
}



int main() {
    BiTree root = NULL;
    InitBiTree(root);
    cout << "请按先序次序输入二叉树,#表示空树" << endl;
    CreatBiTree(root);
    cout << "二叉树深度优先搜索的结果为" << endl;
    PreOrderTraverse(root);

    return 0;
}

#include <stdio.h>

typedef struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
} TreeNode;

TreeNode *buildTree(int n, int *preOrder, int *inOrder, int *outOrder) {
    // 判断输入序列是否合法
    if (n <= 0 || preOrder == NULL || inOrder == NULL || outOrder == NULL) {
        return NULL;
    }

    // 在中序序列中找到根节点的位置
    int rootIndex = 0;
    while (rootIndex < n && inOrder[rootIndex] != preOrder[0]) {
        rootIndex++;
    }

    // 创建根节点
    TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode));
    root->val = preOrder[0];
    root->left = NULL;
    root->right = NULL;

    // 递归构建左子树
    int leftSubtreeSize = rootIndex;
    int *leftPreOrder = preOrder + 1;
    int *leftInOrder = inOrder;
    int *leftOutOrder = outOrder;
    root->left = buildTree(leftSubtreeSize, leftPreOrder, leftInOrder, leftOutOrder);

    // 递归构建右子树
    int rightSubtreeSize = n - 1 - rootIndex;
    int *rightPreOrder = preOrder + 1 + rootIndex;
    int *rightInOrder = inOrder + 1 + rootIndex;
    int *rightOutOrder = outOrder + leftSubtreeSize + 1;
    root->right = buildTree(rightSubtreeSize, rightPreOrder, rightInOrder, rightOutOrder);

    return root;
}

int main(void) {
    int n = 5;
    int preOrder[5] = {1, 2, 3, 4, 5};
    int inOrder[5] = {3, 2, 4, 1, 5};
    int outOrder[5];

    TreeNode *root = buildTree(n, preOrder, inOrder, outOrder);

    return 0;
}

这道题可以使用动态规划来解决。

首先,我们可以使用一个二维数组 $dp[i][j]$ 表示在计算矩阵 $A_i \cdots A_j$ 连乘积的最小乘次数。这个数组的每一个元素都可以由更小范围内的矩阵连乘转移而来。具体地,我们可以枚举 $k$,使得 $i \leq k < j$,然后计算出 $dp[i][j] = \min(dp[i][j], dp[i][k] + dp[k+1][j] + p[i-1]p[k]p[j])$。

除了计算最小乘次数之外,我们还需要记录下来矩阵连乘的次序。我们可以使用一个二维数组 $s[i][j]$ 表示在计算矩阵 $A_i \cdots A_j$ 连乘积时,$dp[i][j]$ 这个值是由哪个矩阵转移而来的。这样,我们就可以通过 $s$ 数组得到矩阵连乘的次序。

最后,我们可以通过递归的方式来输出矩阵连乘的次序。具体来说,我们可以写一个函数,输入为 $i$ 和 $j$,然后判断 $i=j$ 的情况,输出 $i$。否则,我们输出 $-1$,然后调用递归函数来处理 $i$ 到 $s[i][j]$ 之间的矩阵,然后再输出 $s[i][j]+1$


 
#include<iostream>
 
using namespace std;
#define OK 1
#define ERROR 0
#define FALSE -1
#define OVERFLOW -2
 
typedef char TElemType;
typedef int Status;
 
typedef struct BiTNode {
    TElemType data;
    struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
 
 
//初始化
Status InitBiTree(BiTree T) {
    if (!(T = new BiTNode)) return ERROR;
    T->lchild = NULL;
    T->rchild = NULL;
    return OK;
}
 
Status DestoryBiTree(BiTree& T) {
    if (!T) return FALSE;
    else {
        if (T->lchild != NULL)
            DestoryBiTree(T->lchild);
        if (T->rchild != NULL)
            DestoryBiTree(T->rchild);
 
        delete T;
        return OK;
    }
}
 
 
BiTree Root(BiTree T) {
    if (T == NULL) return NULL;
    return T;
}
 
 
Status ClearBiTree(BiTree T) {
    BiTNode* p;
    p = T;
    if (p) {
        DestoryBiTree(p);
        T->lchild = NULL;
        T->rchild = NULL;
        return OK;
    }
}
 
//用前序遍历的递归方式实现深度优先搜索
void PreOrderTraverse(BiTree T) {
    //T为树根的指针
    //如果T非空
    if (T) {
        //输出T结点的值
        cout << T->data << " ";
        //遍历左子树
        PreOrderTraverse(T->lchild);
        //遍历右子树
        PreOrderTraverse(T->rchild);
    }
    else return;
}
 
//创建二叉树
Status CreatBiTree(BiTree& T) {
 
    char ch;
    cin >> ch;
    if (ch == '#') T = NULL;//#代表二叉树为空树
    else {
        if (!(T = new BiTNode))
            exit(OVERFLOW);
        T->data = ch;//生成根节点
        CreatBiTree(T->lchild);//递归创建左子树
        CreatBiTree(T->rchild);//递归创建右子树
    }
    return OK;
}
 
 
 
int main() {
    BiTree root = NULL;
    InitBiTree(root);
    cout << "请按先序次序输入二叉树,#表示空树" << endl;
    CreatBiTree(root);
    cout << "二叉树深度优先搜索的结果为" << endl;
    PreOrderTraverse(root);
 
    return 0;
}

#include <stdio.h>
#define ElemType char
//节点声明,数据域、左孩子指针、右孩子指针
typedef struct BiTNode{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//先序建立二叉树
BiTree CreateBiTree(){
    char ch;
    BiTree T;
    scanf("%c",&ch);
    if(ch=='#')T=NULL;
    else{
        T = (BiTree)malloc(sizeof(BiTNode));
        T->data = ch;
        T->lchild = CreateBiTree();
        T->rchild = CreateBiTree();
    }
    return T;//返回根节点
}