数据结构 第五章(学习笔记一(数组与广义表))

数组

数组的定义1:一个 N 维数组是受 N 组线性关系约束的线性表。
二维数组的逻辑结构可形式地描述为:
2_ARRAY(D,R)
其中 D={aij} | i=0,1,…,b1-1; j=0,1,…,b2-1;aij∈D0}
R={Row,Col}
Row={<aij,ai,j+1>|0<=i<=b1-1;0<=j<=b2-2;aij,ai,j+1∈D0}
ai,j+1是aij在行关系中的后继元素。
Col={<aij,ai+1,j>|0<=i<=b1-2;0<=j<=b2-1;aij,ai+1,j∈D0}
ai+1,j是aij在列关系中的后继元素。
①每一个数组元素a[i][j]都受两个关系Row和Col的约束:
ROW(行关系):ai,j+1 是aij在行关系中的直接后继。
COL(列关系):ai+1,j是aij在列关系中的后继元素。
②每个数组元素属于同一数据类型。
③每个数组元素由下标(i,j)唯一确定其位置。
④每个下标i由bi限定其范围,0≤i≤bi-1
n维数组的逻辑结构可描述为:
n_ARRAY(D,R)
D—数组的元素
R—定义为数组元素间的关系
R=(R1,R2,…,Rn)

数组的定义2 :一维数组是定长线性表; 二维数组是一个定长线性表,它的每个元素是一个一维数组;n维数组是线性表,它的每个元素是n-1维数组。
数组是线性结构,基于两点:
1、一个 n维数组被定义为一个线性表,它的元素是一个 n-1维数组。
2、一个 n维数组的数据元素受n个关系的约束,且每个关系都是线性的。



其中: cn =L, ci-1= bi × ci, 1<i ≤ n ; ci 为常数
上式称为n维数组的存储映象函数

数组的基本操作:
1、数组初始化:确定数组维数、长度,分配存储空间。
initarray(&A,n,bound[ ]);
bound[ ]= b1,b2…bn
2、撤消数组
destroyarray (&A);
3、求数组元素值
value(A,&e,index[ ]);
index[ ]= i1,i2,…in
4、为数组元素赋值
assign(&A,e,index[ ]);

数组的顺序表示及实现:
用一遍地址连续的存储单元依次存放数据元素。
1、数据类型描述
#define MAX_ARRAY_DIM 8
** typedef struct {
ElemType *base; //数组元素空间
int dim; //数组维数
int bounds; //数组维长
int constant; //常数因子
}ARRAY;

C语言实现数组基本操作完整代码

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>//标准头文件,提供宏va_start、va_arg和va_end用于存取变长参数表
#define MAX_ARRAY_DIM 8//假设数组维数最大值为8

typedef struct {
	int* base;//数组元素基址
	int dim;//数组维数
	int* bound; //数组维界基址,即用于存储每一维的长度
	int* constants;//数组映像函数的各个常量系数
}Array;

void InitArray(Array* A, int dim, ...) {
	if (dim<1 || dim>MAX_ARRAY_DIM)
		return;
	A->dim = dim;
	A->bound = (int*)malloc(dim * sizeof(int));
	
	int elemtotal = 1;
	va_list ap;
	va_start(ap, dim);
	for (int i = 0; i < dim; i++) {
		A->bound[i] = va_arg(ap, int);
		elemtotal *= A->bound[i];
	}
	va_end(ap);

	A->base = (int*)malloc(sizeof(int) * elemtotal);
	A->constants = (int*)malloc(dim * sizeof(int));
	A->constants[dim - 1] = 1;

	for (int i = dim - 2; i >= 0; i--) {
		A->constants[i] = A->bound[i + 1] * A->constants[i + 1];
	}
}

void DestroyArray(Array* A){
    if (!A->base)
        return;
    free(A->base);
    A->base = NULL;
    if (!A->bound){
        return;
    }
    free(A->bound);
    A->bound = NULL;

    if (!A->constants){
        return;
    }
    free(A->constants);
    A->constants = NULL;
}

bool Locate(Array* A, va_list ap, int* off){
    *off = 0;
    for (int i = 0; i < A->dim; ++i){
        int ind = va_arg(ap, int);  //依次取出每一维的下标
        if (ind < 0 || ind > A->bound[i])
            return false;
        (*off) += A->constants[i] * ind;//计算待存取的元素和数组基址的距离
    }
    return true;
}

void Value(Array* A, int* e, ...){
    va_list ap;
    va_start(ap, e);
    int off;
    if (!Locate(A, ap, &off)){
        return;
    }
    *e = *(A->base + off);
}

void Assign(Array* A, int e, ...){
    va_list ap;
    va_start(ap, e);
    int off;
    if (!Locate(A, ap, &off)){
        return;
    }
    *(A->base + off) = e;
}

int main(){
    Array arr;
    InitArray(&arr, 3, 3, 4, 5);
    for (int i = 0; i < 3; ++i){
        for (int j = 0; j < 4; ++j){
            for (int k = 0; k < 5; ++k){
                Assign(&arr, i + j + k, i, j, k);
            }
        }
    }

    printf("遍历数组arr:\n");
    for (int i = 0; i < 3; ++i){
        for (int j = 0; j < 4; ++j){
            for (int k = 0; k < 5; ++k){
                int tmp = 1;
                Value(&arr, &tmp, i, j, k);
                printf("%5d", tmp);
            }
            printf("\n");
        }
        printf("\n");
    }
    printf("\n");

    return 0;
}

矩阵的压缩存储:
1、矩阵压缩存储的概念
特殊矩阵:值相同元素或0元素在矩阵中分布有一定规律。
⒈对称矩阵:矩阵中的元素满足
aij=aji 1≤i,j≤n
⒉三角矩阵:上(下)三角矩阵指矩阵的下(上)三角(不包括对角线)中的元素均为常数c或0的n阶矩阵。
⒊对角矩阵(带状矩阵):矩阵中所有非0元素集中在以主对角线为中心的区域中。
稀疏矩阵:非0元素很少( ≤ 5%)且分布无规律。
2、矩阵的压缩存储
为多个相同值的元分配一个存储单元;对零元不分配空间。
对称矩阵的压缩存储
存储分配策略: 每一对对称元只分配一个存储单元,即只存储下三角(包括对角线)的元, 所需空间数为:
n×(n+1)/2。
存储分配方法: 用一维数组sa[n(n+1)/2]作为存储结构。
sa[k]与aij之间的对应关系为:
稀疏矩阵存储分配策略
只存储稀疏矩阵的非0元素。
矩阵中的一个元素可以用行列下标和其值来唯一表示,因此可以用一个三元组(i,j,aij) 唯一确定一个非0元素。
逻辑上,用三元组表来表示稀疏矩阵的非0元

广义表

广义表的定义
广义表又称为列表(lists),是n≥0个元素a1,a2,…,an的有限序列,记为:
A=( a1,a2,…,an)
其中:
A是广义表的表名,n是广义表的长度
ai 是单个元素或广义表,
若ai是单个元素,则称为广义表的单元素(或原子)。
若是广义表,则称ai是广义表的子表。所以广义表又称为列表。
即 ai ∈D0 或 ai ∈lists
广义表的表头(Head):非空表A 的第一个元素 a1。
广义表的头与a1具有相同的表示形式。
广义表的表尾(Tail):除其头之外的其余元素( a2,…,an)组成的表。
广义表的尾一定是一个广义表。
特点:广义表的定义是一个递归的定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值