多维数组(数据结构)

1. 多维数组

1.1多维数组的存储:

L O C ( A [ j 1 ] [ j 2 ] ⋯ [ j n ] ) = L O C ( A [ c 1 ] [ c 2 ] ⋯ [ c n ] ) + ∑ i = 1 n α i ∗ ( j i ) − c i ( 1 ≤ i ≤ n ) \small \small \small LOC(A[j_1][j_2]\cdots[j_n]) = LOC(A[c_1][c_2]\cdots[c_n])+\displaystyle\sum_{i=1}^n\alpha_i*(j_i)-c_i( 1 \leq i \leq n)\small \small \small LOC(A[j1][j2][jn])=LOC(A[c1][c2][cn])+i=1nαi(ji)ci(1in)
其中 a i = s i z e ∗ ∏ k = i + 1 n ( d k − c k + 1 ) , ( 1 ≤ i ≤ n ) a_i = size*\displaystyle\prod_{k = i+1}^n(d_k-c_k+1),(1\leq i \leq n) ai=sizek=i+1n(dkck+1),(1in)
所以可得到某数据元素存储位置为:

# include <iostream>
# include <algorithm>
# include <cstring>
using namespace std;
const int MAXSIZE = 100001;

int main(void)
{
    int n, size = 2;
    int c[MAXSIZE] = {0}, d[MAXSIZE] = {0}, j[MAXSIZE], a[MAXSIZE] = {0};
    int LOC_1 = 0, LOC_2 = 0;
    cout << "请输入数组的维数:" << endl;
    cin >> n;
    cout << "请输入数组的上下限:" << endl;

    cout << "上限为:" << endl;
    for(int i = 1;  i <= n; i++){
        cin >> c[i];
    }
    cout << "下限为:" << endl;
    for(int i = 1;  i <= n; i++){
        cin >> d[i];
    }

    cout << "请输入下线地址" << endl;
    cin >> LOC_1;
    cout << "请输入计算元素的下标:" << endl;
    for(int i = 1; i <= n; i++){
        cin >> j[i];
    }

    for(int i = 1; i <= n; i++){
        int sum = 1;
        for(int k = i+1; k <= n; k++){
            sum *= (d[k] - c[k] + 1);
        }
        a[i] = size*sum;
    }
    int sum = 0;

    for(int i = 1; i <= n; i++){
        sum += a[i] * (j[i] - c[i]);
    }

    LOC_2 = LOC_1 + sum;
    cout << LOC_2 << endl;
    system("pause");
    return 0;
}

1.2 特殊矩阵:
(1)三角矩阵:
  三角矩阵分为上三角矩阵和下三角矩阵两种。由于三角矩阵有一半元素为0或者为常数,所以如果用普通二维数组存储三角矩阵会浪费很多空间,因此我们可以将矩阵压缩。可以将三角矩阵中的有效元素放在一维数组中,常数项仅需存到一维数组中的最后一个单元即可。
 可得到上三角矩阵按行序为主序的存储地址:
L O C ( A [ i ] [ j ] ) = L O C ( A [ 1 ] [ 1 ] ) + ( ( i − 1 ) ( 2 n − i + 2 ) / 2 + ( j − i ) ) ∗ s i z e \small \small LOC(A[i][j]) = LOC(A[1][1]) + ((i-1)(2n-i+2)/2+(j-i)) * size \small \small LOC(A[i][j])=LOC(A[1][1])+((i1)(2ni+2)/2+(ji))size
 同理可得到下三角矩阵按行序为主序的存储地址为:
L O C ( a [ i ] [ j ] ) = L O C ( A [ 1 ] [ 1 ] ) + ( i ( i − 1 ) / 2 + ( j − 1 ) ) ∗ s i z e \small \small LOC(a[i][j]) = LOC(A[1][1])+(i(i-1)/2+(j-1))*size \small \small LOC(a[i][j])=LOC(A[1][1])+(i(i1)/2+(j1))size

1.3 稀疏矩阵:
(1)三元组顺序表示法:
  稀疏矩阵中的有效元素数量少且分布零散,所以用普通数组存储必然会浪费空间,所以可以建立一个顺序表,包含了有效元素的行、列、数值;
可建立结构体如下:

typedef int ElementType;
typedef struct {
    int row, col;
    ElementType value;
}Triple;

typedef struct {
    Triple data[MAXSIZE];
    int rows, cols, nums;
}TSMatrix;

(2)转置运算:
1.按列序递增进行转置: 按 列 序 递 增 进 行 转 置 : O ( A . c o l ∗ A . n u m s ) \small \small 按列序递增进行转置:O(A.col*A.nums) O(A.colA.nums)

void TransposeTSMatrix(TSMatrix A, TSMatrix * B){
    int i, j, k = 1;
    B->cols = A.cols;
    B->rows = A.rows;
    B->nums = A.nums;
    if(B->nums <= 0) return;

    for(i = 1; i <= A.cols; i++){
        for(j = 1; j <= A.nums; j++){
            if(A.data[j].col == i){
                B->data[k].col = A.data[j].row;
                B->data[k].row = A.data[j].col;
                B->data[k].value = A.data[j].value;
                k++;
            }
        }
    }
    return;
}
  1. 控制元素个数,减少第一种算法多余步骤:
void TransposeTSMatrix2(TSMatrix A, TSMatrix *B){
    int count = 0;
    B->cols = A.cols;
    B->rows = A.rows;
    B->nums = A.nums;
    if(B->nums <= 0) return;

    for(int i = 0; i < A.cols; i++){
        for(int j = 0; j < A.nums; j++){
            if(A.data[j].col == i+1){
                B->data[count].col = A.data[j].row;
                B->data[count].row = A.data[j].col;
                B->data[count++].value = A.data[j].value;
                if(count > A.nums) return ; //count > A中元素个数,说明已完成转置
            }
        }
    }
    return;
}
  1. 对于列分布跨度较大的矩阵:
     可以对原三元组进行查找最小列,然后存进转置三元组中,这样可减少循环次数;
    改 进 后 : O ( A . n u m s ∗ A . n u m s ) \small \small 改进后:O(A.nums*A.nums) O(A.numsA.nums)
void TransposeTSMatrix3(TSMatrix A, TSMatrix *B){
    int count = 0, min = 0;
    B->cols = A.cols;
    B->rows = A.rows;
    B->nums = A.nums;
    if(B->nums <= 0) return;

    for(int i = 0; i < A.nums; i++){
        min = 0;
        for(int j = 1; j < A.nums; j++){
            if(A.data[j].col < A.data[min].col) min = j;
        }
        B->data[i].col = A.data[min].row;
        B->data[i].row = A.data[min].col;
        B->data[i].value = A.data[min].value;
        A.data[min].col = A.cols+1;
    }
    return;
}

  1. 一次定位快速转置:
    O ( A . c o l s ) \small \small O(A.cols) O(A.cols)
void TransposeTSMatrix4(TSMatrix *A, TSMatrix *B){
    int num[MAXSIZE] = {0}, position[MAXSIZE];
    B->cols = A->cols;
    B->rows = A->rows;
    B->nums = A->nums;
    if(B->nums <= 0) return;

    for(int i = 1; i <= A->nums; i++){
        num[A->data[i].col]++;    //存放每一列非零元素的个数
    }
    position[1] = 1;
    for(int i = 2; i <= A->cols; i++){
        position[i] = position[i - 1] + num[i - 1];  //存放转置矩阵中,每一行在三元表中的位置;
    } // position[col] 表示第col列在三元表中的位置;

    for(int i = 1; i <= A->nums; i++){
        int col = A->data[i].col;
        int q = position[col];

        B->data[q].row = A->data[i].col;
        B->data[q].col = A->data[i].row;
        B->data[q].value = A->data[i].value;
        position[col]++;
    }

}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值