递归方法计算行列式(C语言编写)

递归方法计算行列式

1.功能介绍

主要功能为求算n阶行列式的值,理论上,n没有限制。
采用的数学方法为:不断进行拉普拉斯展开,直至化为二阶行列式。
代码行数:功能代码约100行左右。

2.编码过程分析

  1. 首先编码求取二阶行列式的函数
  2. 编码求取三阶行列式的函数
    此时要复用求取二阶行列式的函数
    将三阶行列式进行展开
  3. 将求二阶与三阶合并到一个函数中
    通过条件控制语句进行划分
    此时实现了最简单的递归情况
  4. 将二阶三阶的情况扩展到n阶

3.源码

#include<stdio.h>
#include<math.h> //pow求子式符号
#include<stdlib.h> //动态内存分配
float *InputMatrix (int n);
float CalculateSecondDimension(float *matrix);
float CalculateMatrix(float *matrix,int n);
void GetSubmatrix(float *matrix,float *submatrix,int n,int neglect_line);
void PrintMatrix(float *matrix,int n);

int main()
{
    float *matrix=NULL;
    float result;
    int line_number;
    printf("Please enter matrix size n(1<=n<20):");
    scanf("%d",&line_number);
    matrix=InputMatrix(line_number);
    PrintMatrix(matrix,line_number);
    result=CalculateMatrix(matrix,line_number);
    printf("result = %f\n",result);
    free(matrix);
    return 0;
}
/*功能:创建并输入所求行列式
参数:行列式的行数
返回值:指向该行列式第一个元素的指针
*/
float *InputMatrix (int n)
{
    int i,j;
    float *matrix;
    matrix=(float *)calloc(n*n,sizeof(float));
    printf("Please input matrix line by line:\n");
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%f",&matrix[i*n+j]);
        }
    }
    return matrix;
}

/*功能:输出一个行列式的所有元素
参数:指向该行列式第一个元素的指针matrix
    行列式行数n
*/
void PrintMatrix(float *matrix,int n)
{
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            printf("%6.1f\t",matrix[i*n+j]);
        }
        printf("\n");
    }
}

/*功能:计算行列式matrix的值
参数:指向行列式第一个元素的指针matrix,行列式行数n
返回值:行列式matrix的值
主要方法:递归,拉普拉斯展开
*/
float CalculateMatrix(float *matrix,int n)
{
    int i;
    float sum=0;
    float submatrix_value;
    if(n==2)
    {
        return matrix[0]*matrix[3]-matrix[1]*matrix[2];
    }
    else
    {
        for(i=0; i<n; i++)
        {
            float *submatrix=NULL;
            submatrix=(float *)calloc((n-1)*(n-1),sizeof(float));
            GetSubmatrix(matrix,submatrix,n,i);
            submatrix_value=CalculateMatrix(submatrix,n-1);
            free(submatrix);
            sum=sum+powf(-1,i)*matrix[i]*submatrix_value;
        }
        return sum;
    }

}

/*功能:求行列式的一个子式(去掉第0行和第neglect_line列)
参数:指向原行列式第一个元素的指针matrix
    指向子式第一个元素的指针submatrix
    需要去掉的那一列neglect_line
*/
void GetSubmatrix(float *matrix,float *submatrix,int n,int neglect_line)
{
    int i,j,k;
    for(i=0;i<n-1;i++)
    {
        for(j=0,k=0;j<n-1;k++)
        {
            if(k!=neglect_line)
            {
                submatrix[i*(n-1)+j]=matrix[(i+1)*n+k];
                j++;
            }
        }
    }

}

4.处理细节

  • 数据结构:
    存储行列式使用的是指针类型,而不是数组类型
    优点:方便作为参数在各个函数间进行传递
    下面详细解释:
    一想到行列式,我们会认为用数组储存更直观,更好理解
    在实现三阶行列式的计算时,用二维数组没有问题
    但是当扩展到高阶时
    随之而来的有两个问题:
    1. 因为我们使用的方法是拉普拉斯展开
      就必须要求一个高阶行列式的子式
      当我们存储这个子式时,想继续使用数组类型就变得很困难
      困难首先表现在对数组的创建上
      众所周知,C语言中对数组进行创建时,元素个数必须为常量
      而子式的行数并不确定
      其必定是由一个未知数,所以无法完成数组的创建
    2. 同理的,在函数对二维数组(一维数组就没有这个问题)进行参数传递时,列数量也必须为常数,即a[ ][N]
      而N同问题1,也应该为变量

5.不足之处

  • 频繁地进行动态内存的分配来对行列式及其子式进行储存
    是否会产生对内存的大量占用,
    或者常见的因内存问题而产生的安全问题?
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值