栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

计算N阶行列式(C语言)(降阶法)(函数递归)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

计算N阶行列式(C语言)(降阶法)(函数递归)

一般比较常见的是3阶和4阶的行列式,3阶行列式可以很方便的直接算出结果,而4阶的行列式却无法运用和3阶行列式类似的公式直接进行计算,必须用降阶法或者其他方法来求解。那么当行列式的阶数是5阶甚至6阶呢?计算的复杂程度无疑是疯狂上涨的,就算真的算出来了,相信这个过程也会让你回味无穷。

为了解救劳苦大众于水深火热之中,笔者特此发布本人用于计算N阶行列式的代码,以方便大众。

声明:以下文章中涉及动态内存分配,为求方便,笔者将用数组这个不那么准确但更好理解的方式代为称呼

以下,为详细讲解:

主要思路是降阶法, 降阶法 ( 按行 或列展开)在此不多赘述,相信百度可以给你一个满意的答案。

头文件: stdio.h 和 stdlib.h

主函数部分:

int main(void)
{
    int order;
    printf("Please enter determinant order:n");
    scanf("%d", &order);

    int *D = InputData(order);
    int Rslt = Reduction(D, order);

    printf("Result:%d", Rslt);

    free(D);

    return 0;
}

order意为行列式阶数;printf的语句意思为请输入行列式的阶数;函数InputData用于录入行列式的各个元素并返回用于储存数据的数组的首地址;D为指向数组首地址的指针,同时也代表了行列式(D取自英文单词determinant首字母);Rlst为行列式计算结果;函数Reduction代表用降阶法计算行列式并返回结果,很显然,通篇文章的精华就在这个函数里,笔者也会花费大量篇幅进行讲解。

函数部分:

int *InputData(int order)
{
    int Row, Col;
    int *D = (int *)malloc(sizeof(int) * order * order);

    printf("Please enter the elements of the determinant:n");
    for (Row = 0; Row < order; Row++)
        for (Col = 0; Col < order; Col++)
            scanf("%d", D + Row * order + Col);

    return D;
}

int Reduction(int *D, int order)
{
    int Rslt = 0;
    if(order>3)
    {
        int Col;
        for (Col = 0; Col < order; Col++)//所有传入此函数的行列式都按第一行展开
        {
            int *Cofactor = (int *)malloc(sizeof(int) * (order - 1) * (order - 1));
            int pos = 0;
            int row, col;
            for (row = 1; row < order; row++)
                for (col = 0; col < order; col++)
                    if(col==Col)
                        continue;
                    else
                        Cofactor[pos++] = D[row * order + col];

            int sign = 1;
            if((Col+2)%2)
                sign = -1;

            Rslt += D[Col] * sign * Reduction(Cofactor, order - 1);
            free(Cofactor);
        }
    }
    else
    {
        if(order==3)
            Rslt = (D[0] * D[4] * D[8] + D[1] * D[5] * D[6] + D[2] * D[3] * D[7] - 
                    D[2] * D[4] * D[6] - D[1] * D[3] * D[8] - D[0] * D[5] * D[7]);
        else if(order==2)
            Rslt = D[0] * D[3] - D[1] * D[2];
        else
            Rslt = D[0];
    }
    return Rslt;
}

函数InputData很容易实现,在此不过多赘述。(row和col分别代表行和列的意思)

函数Reduction大体分为两部分:

part1:当阶数order小于等于3时(阶数为1或2或3时),直接利用公式导出结果。

part2:当阶数大于3时,反复调用函数Reduction进行降阶处理。具体为:先创建一个n-1阶的余子式数组(Cofactor),从原行列式中找出属于该余子式的元素并由cofactor储存,然后进行余子式符号(sign)的判定,然后用Rslt加上"元素乘以对应余子式再乘以符号"的值,最后释放掉申请的数组cofactor。由于一个n阶行列式按某行展开后有n个余子式,所以重复以上过程n次,Rslt加了n次数值后,其结果就为行列式的值。

4阶行列式求解过程详解:

首先原行列式如下(申请的内存为n*n,线性的下文中的余子式数组同理)

D0      D1      D2      D3  

D4      D5      D6      D7  

D8      D9      D10    D11

D12    D13    D14    D15

然后再申请一个(n-1)*(n-1)大小的余子式数组(cofactor),将原行列式中的对应元素赋予它(本文中每个传入reduction函数的行列式都是按第一行展开)

那么D0余子式为:

C0  =D5  ,  C1  =D6  ,  C2  =D7  ,

C3  =D9  ,  C4  =D10,  C5  =D11,

C6  =D13,  C7  =D14,  C8  =D15,

确定符号之后将余子式数组C传进reduction函数中计算结果并返回,然后进一步处理后被rslt加上。

D1,D2,D3的余子式同理,最后的rslt就为行列式值。

大体处理步骤就是将n阶行列式通过reduction函数化为n-1阶行列式,然后n-1阶行列式又通过reduction函数化为n-2阶行列式,然后n-2阶行列式又通过reduction降阶,直到阶数化为3时用公式计算出结果,然后层层返回各阶余子式结果rslt,最后加回到n阶的rslt中得出结果,其实也就是函数递归。

在这里贴一个网站,可以在线免费计算50阶及以下的行列式,网址:在线求行列式的值

您可以比较本文中的程序的计算结果与该网站的计算结果,若有bug欢迎在评论区提出。

再附一个5阶行列式:

5 8 9 4 5
7 8 9 2 1
3 2 1 4 5
8 9 7 5 1
1 2 4 5 7

结果为:972

如果您还有更优解法,欢迎在评论区留言。

如果您对此文章有疑问,也欢迎在评论区留言,我很乐于解答。

最后,如果您对以上内容满意,不妨点个免费的支持我,咱们下个文章见!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/867240.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号