2018.11.23学习记录

1.压缩存储

转载自:https://www.cnblogs.com/lnlin/p/6852236.html

/*
数组的压缩储存:
    在一些高阶矩阵中,非零元素非常少,此时如果使用二维数组将造成
    储存空间的浪费,这时可只储存部分元素,从而提高储存空间的利用
    率,通常的做法是为多个相同值的元素只分配一个储存单元,对值为
    零的元素不分配储存单元。我们把非零元素个数远小于二维数组总元
    素个数,或元素分布呈一定规律的(对称矩阵,三角矩阵,对角矩阵)
    特殊矩阵压缩储存。
    
    对称矩阵:
        矩阵元素的值与下标的关系: a(i,j) = a(j,i)
        我们只需为每一对称元素分配一个储存单元,这样可以将 n*n 个
        元素储存在一个 n(n+1)/2 的储存空间里。
        假设用以为数组储存上三角或下三角元素。则一维数组的下标 k
        与 n 阶对称阵的元素 a(i,j) 的下标对应关系为:
            如果 i >= j 时,以下三角储存, k = i*(i+1)/2 + j
            如果 i < j  时,以上三角储存, k = j*(j+1)/2 + i
            
    三角矩阵:
        分为上三角矩阵和下三角矩阵,其中在上三角矩阵中,下三角元素
        全部为一个常数c,下三角矩阵中,上三角元素全部为一个常数c。
        以上三角矩阵为例,上三角矩阵的压缩规则是只储存上三角元素,
        不储存下三角元素,或只用一个储存单元储存下三角非零元素
        用一维数组储存上三角矩阵,采取使用一个储存单元储存下三角元
        素的方法,一维数组的长度为 n*(n+1)/2 + 1 一维数组的下标 k与
         n 阶上三角矩阵的元素 a(i,j) 的下标对应关系为:
            如果 i <= j, k = i*(2n-i+1)/2 + j -i
            如果 i > j , k = n*(n+1)/2 
        下三角矩阵使用一维数组储存后相应的对应关系为:
            如果 i >= j, k = i*(i+1)/2 + j
            如果 i <  j, k = n*(n+1)/2 
        
        其中第 k = n*(n+1)/2 的位置存放的是常数 c 
        
        以上三角矩阵为例:
        # include <stdio.h>
        # define N 5
        
        int main(void)
        {
            int arry[N][N];
            int arr[N*(N+1)/2 + 1] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
            int i, j, k;
            for (i = 0; i < N; ++i)
            {
                for (j = 0; j < N; ++j)
                {
                    if (i <= j)
                    {
                        k = i*(2*N-i+1)/2 + j -i;
                        arry[i][j] = arr[k];
                    }
                    else
                    {
                        k = N*(N+1)/2;
                        arry[i][j] = arr[k];
                    }
                }
            }
            for (i = 0; i < N; ++i)
            {
                for (j = 0; j < N; ++j)
                    printf("%-5d", arry[i][j]);
                
                printf("\n");
            }
            
            return 0;
        }
        
        输出结果:
   2    3    4    5
   6    7    8    9
   0    10   11   12
   0    0    13   14
   0    0    0    15 
         
        
    对角矩阵:(数学上的问题 <-0-0->) 
        也称为带状矩阵,就是所有的非零元素都集中在以对角线为中心的带状 
        区域内(对角线的个数位奇数),即除了主对角线和主对角线上下若干
        条对角线的元素外,其它元素均为常数 c . 
*/ 

/*
假设已有一个 n*n 的 上三角矩阵 A ,且上三角矩阵 A 的元素已按行为主序连续压缩 
存放在数组 B 中,设计一个算法,将 B 中的元素案列为主序连续压缩存放在数组 C中
2  3  4  5 
6  7  8  9
A(5*5) = 0 0 10 11 12 
0  0 13 14
0  0  0 15   
其中 B = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0},
     C = { 1, 2, 6, 3, 7, 10, 4, 8, 11, 13, 5, 9, 12, 14, 15, 0}.
     
思路:将一维数组B还原成二维数组A,再将二维数组储存在C中
*/ 

# include <stdio.h>
# define N 5

void Trans_To_Original(int arry[N][N], int * arr);
void Trans_To_Compress(int arry[N][N], int * arr);
void Show(int arry[N][N], int * arr1, int * arr2); 

int main(void)
{
    // 创建一个一维数组储存已知的以行为主序压缩后所得元素 
    int B[(N+1)*N/2 + 1] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
    int A[N][N] = {0};
    Trans_To_Original(A, B);
    
    // 创建一个一维数组储存以列为主序压缩所得的数据
    int C[(N+1)*N/2 + 1];
    Trans_To_Compress(A, C);
    
    // 将三个数组打印输出 
    Show(A, B, C);
    
    return 0;
}

void Trans_To_Original(int arry[N][N], int * arr)
{
    int i, j, k;
    for (i = 0; i < N; ++i)
    {
        for (j = 0; j < N; ++j)
        {
            if (i <= j)
            {
                k = i*(2*N-i+1)/2 + j -i;
                arry[i][j] = arr[k];
            }
            else
            {
                k = N*(N+1)/2;
                arry[i][j] = arr[k];
            }
        }
    }
    
    return;
}

void Trans_To_Compress(int arry[N][N], int * arr)
{
    int i, j, k = 0;
    // 按列为主序压缩 
    for (i = 0; i < N; ++i)
    {
        for (j = 0; j <= i; ++j)
        {
            arr[k++] = arry[j][i];
        }
    }
    arr[(N+1)*N/2] = 0;
    
    return;
}

void Show(int arry[N][N], int * arr1, int * arr2)
{
    int i, j, k;
    printf("原二维数组为:\n");
    for (i = 0; i < N; ++i)
    {
        printf("              ");
        for (j = 0; j < N; ++j)
        {
            printf("%-5d", arry[i][j]);
        }
        printf("\n");
    }
    printf("以行为主序压缩所得结果为:\n");
    for (k = 0; k < (N+1)*N/2; ++k)
    {
        printf("%-3d", arr1[k]);
    }
    printf("\n以列为主序压缩所得结果为:\n");
    for (k = 0; k < (N+1)*N/2; ++k)
    {
        printf("%-3d", arr2[k]);
    }
    printf("\n");
    
    return;
}

 2.广义表

转载自:龙猫小爷
链接:https://www.jianshu.com/p/2469a4d9708e
來源:简书

广义表:是由零个或多个原子或子表组成的优先序列,是线性表的推广。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

广义表的存储结构

广义表中的数据元素可以具有不同的结构,因此,难以用顺序存储结构表示,通常采用链式存储结构,每个数据元素可用一个节点表示。由于广义表中有两种数据元素,因此需要有两种结构的节点——一种是表结点,一种是原子结点。

表结点由三个域组成:标志域、指示表头的指针的指针域和指示表尾的指针域;而原子域只需两个域:标志域和值域。                                                  

 

 

 

 

 

表结点由三个域组成:标志域、指示表头的指针域和指向下一个元素的指针;原子结点的三个域为:标志域、值域和指向下一个元素的指针。

 

 

 

 

 


 

3.记录:

(1)对矩阵压缩存储是为了减少存储空间;

(2)()优先级大于【】大于*:

         int(*p)[4]-----定义一个p为指向有4个int元素的数组的指针;

         int *p[4]-----定义一个存放四个整型指针的数组p

(3)广义表表头空不代表该表为空:广义表()和(())不同,前者是长度为0的空表,对其不能做求表头和表尾的运算,后者为长度为1的非空表,对其可进行分解,得到的表头和表尾均是空表()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值