筆者最近在學習線性代數,寫了一個求解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運行結果: