n階行列式求解

筆者最近在學習線性代數,寫了一個求解n階行列式的程序,拿出來給大家分享借鑑一下。
/*

    1.名字:   determinant.c

    2.功能:   求解n階行列式值

    3.編者:   HeavenMo <[email protected]>

    4.時間:   2015-10-2 22:42

    5.敘述:   遞歸法實現n階行列式的求解

    6.申明:   Win 8.1 pro / GCC 4.8.1編譯器親測通過

    7.結構:
                a)main函數部分完成行列式的輸入操作

                b)det函數完成行列式的值的返回

                c)det函數中,將原來的n階行列式不斷的遞歸分解,

                如,n階矩陣分解爲n個(n-1)階餘子矩陣,(n-1)階分解成(n-1)個(n-2)階餘子矩陣,

                ...,以此類推

                d)遞歸至2階時,計算2階行列式的值,並返回給上一層,...,

                以此類推

*/

//有關頭文件的包含,因爲要用到動態內存的分配,所以包含stdlib.h
# include <stdio.h>

# include <stdlib.h>

//定製數據類型,方便修改
typedef int data_type;

typedef unsigned int uint;

//計算n階行列式的函數聲明
data_type det(data_type *p, uint n);

int main(void)
{
    //n爲行列式的階數,i,n,m爲非負值,所以定義爲uint
    uint i, n, m;

    //提示輸入行列式的階數
    printf("請輸入行列式的階數:\n");
    scanf("%u", &n);
    m = n * n;

    //程序的關鍵所在,將n階行列式看成是一個長度是n*n的一維數組,m爲數組的長度
    data_type *p = (data_type *)calloc(m, sizeof(data_type));

    printf("請輸入行列式的元素值:\n");
    for(i = 0; i < m; i++)
    {
        scanf("%d", p + i);
    }

    printf("\n所求行列式的值 = %d\n", det(p, n));

    //釋放相應的內存
    free(p);
    return 0;
}

//p指向長度爲n*n的數組,n爲行列式的階數
data_type det(data_type *p, uint n)
{
    //n = 1時的情況
    if(n == 1)
    {
        return *p;
    }

    //遞歸基準
    if(n == 2)
    {
        return ((*p) * (*(p + 3)) - (*(p + 1)) * (*(p + 2)));
    }

    //m1:當前行列式的元素個數,m2:分解後的行列式的元素個數
    uint i, j, k, m1, m2;
    m1 = n * n;
    m2 = (n - 1) * (n - 1);

    //爲分配後的n個n-1階的行列式分配內存的基址
    data_type *p_list[n];
    for(i = 0; i < n; i++)
    {
        p_list[i] = (data_type *)calloc(m2, sizeof(data_type));
    }

    //關鍵一步,篩選出代數餘子矩陣,i(0 - n-1):原矩陣可以分解爲n個n-1階代數餘子矩陣
    for(i = 0; i < n; i++)
    {
        //j = n意爲篩選元素要從第二行開始,k變量統計代數餘子矩陣的元素個數
        for(j = n, k = 0; j < m1; j++)
        {
            //考察原矩陣與餘子矩陣的關係,構造餘子矩陣
            if(j % n != i)
            {
                *(p_list[i] + k) = *(p + j);
                k++;
            }
        }
    }

    //根據遞推公式求和,sign爲代數餘子式的符號,與行數(其實是第一行),列數有關
    int sign = -1;
    data_type sum = 0;
    for(i = 0; i < n; i++)
    {
        sign *= -1;

        //調用函數,通過對第一行的各元素與相應的代數餘子矩陣的行列式值之積求和,實現遞歸求值
        sum += sign * (*(p + i)) * det(p_list[i], n - 1);
    }

    //返回函數值
    return sum;
}

附上cmd運行結果:
以下是cmd運行結果:

發佈了35 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章