PAT A1102 Invert a Binary Tree

题目

code

# include <cstdio>
# include <queue>
# include <stack>
# include <algorithm>
# include <cstring>
using namespace  std;
const int maxn=110;
struct node{
    int lchild,rchild;
}Node[maxn];
bool notRoot[maxn]={false};
int n,num=0;
void print(int id){
    printf("%d",id);
    num++;
    if(num<n) printf(" ");
    else printf("\n");
}
//中序遍历
void inOrder(int root){
    if(root==-1){
        return;
    }
    inOrder(Node[root].lchild);
    print(root);
    inOrder(Node[root].rchild);
}
void BFS(int root){
    queue <int> q;
    q.push(root);
    while(!q.empty()){
        int now=q.front();
        q.pop();
        print(now);
        if(Node[now].lchild!=-1) q.push(Node[now].lchild);
        if(Node[now].rchild!=-1) q.push(Node[now].rchild);
    }
}
//后序遍历
void postOrder(int root){
    if(root==-1){
        return;
    }
    postOrder(Node[root].lchild);
    postOrder(Node[root].rchild);
    swap(Node[root].lchild,Node[root].rchild);//交换左右子树
}
int stroToNum(char c){
    if(c=='-') return -1;
    else{
        notRoot[c-'0']=true;
        return c-'0';
    }
}
int findRoot(){
    for(int i=0;i<n;i++){
        if(notRoot[i]==false){
            return i;
        }
    }
    return 0;
}
int main(){
    char lchild,rchild;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%*c%c %c",&lchild,&rchild);
        Node[i].lchild=stroToNum(lchild);
        Node[i].rchild=stroToNum(rchild);
    }
    int root=findRoot();
    postOrder(root);//后序遍历 翻转二叉树
    BFS(root);
    num=0;
    inOrder(root);// 输出中序遍历的结果
    return 0;
}



### 处理奇异矩阵求逆的方法 当遇到需要对奇异矩阵求逆的操作时,由于奇异矩阵不存在真正的逆矩阵,因此直接调用 `np.linalg.inv` 函数将会抛出异常。为了应对这种情况,可以考虑以下几种替代方案: #### 使用伪逆矩阵 对于奇异矩阵或接近奇异的矩阵,计算其Moore-Penrose广义逆(即伪逆)是一个有效的解决方案。Numpy提供了专门用于此目的的功能——`pinv()` 方法。 ```python import numpy as np # 创建一个奇异矩阵作为例子 singular_matrix = np.array([[1, 2], [2, 4]]) try: inv_singular = np.linalg.inv(singular_matrix) except np.linalg.LinAlgError: print("Matrix is singular and cannot be inverted.") pseudo_inverse = np.linalg.pinv(singular_matrix) print(f"Pseudo inverse of the matrix:\n{pseudo_inverse}") ``` 这种方法能够返回最接近原矩阵行为的一个解,在某些应用场景下可能已经足够满足需求[^1]。 #### 添加微扰项使矩阵变为非奇异 另一种常见的做法是在原始数据上加上一个小量的身份矩阵(Identity Matrix),从而使得原本可能是零的行列式变得不等于零,进而允许对其进行常规意义上的反转操作。这通常被称为Tikhonov正则化技术的一部分。 ```python epsilon = 1e-8 * np.eye(len(singular_matrix)) regularized_matrix = singular_matrix + epsilon inverse_with_perturbation = np.linalg.inv(regularized_matrix) print(f"Inverse with perturbation added to make it non-singular:\n{inverse_with_perturbation}") ``` 通过这种方式可以在一定程度上缓解数值不稳定带来的影响,并获得近似的逆矩阵结果[^3]。 #### 应用SVD分解重构逆矩阵 如果目标仅仅是解决问题而不是严格意义上找到精确的逆,则还可以利用奇异值分解(SVD)来构建所谓的“截断”版本的逆矩阵。具体来说就是忽略那些非常小甚至为零的奇异值对应的分量,只保留较大贡献的部分来进行重建工作。 ```python U, s, Vt = np.linalg.svd(singular_matrix, full_matrices=False) threshold = 1e-10 s_inv = np.where(abs(s)>threshold, 1/s, 0.) svd_based_inverse = (Vt.T @ np.diag(s_inv) @ U.T) print(f"SVD based approximate inverse:\n{svd_based_inverse}") ``` 上述三种策略都可以有效地规避因尝试对奇异矩阵执行标准求逆而引发的各种错误情况。选择哪种取决于具体的上下文环境以及最终期望达到的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值