数据结构与算法总结2_常用的数据结构(数组)

本文介绍了数组的基本概念及其实现,包括数组的初始化、销毁、取值和赋值等操作,并详细探讨了映像函数在多维数组中的应用,通过具体实例加深读者对数组的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0.

数组是我们很熟悉的一种数据类型。为了加深对数组的理解,我们在这里用抽象数据类型的形式讨论数组的定义和实现。

1.

数组的几个基本操作如下:

InitArray();    //构造数组
DestroyArray(); //销毁数组
Value();        //取值
Assign();       //给数组的某个元素赋值

数组一般不作插入和删除的操作,所以采用顺序的存储结构表示数组。

在线性代数或者矩阵分析中都学过矩阵,一个2x3的矩阵,可以看成是一个2维列向量,这个列向量的每一个元素又是一个3维行向量。或者这个矩阵可以看成是一个3维行向量,这个行向量的每一个元素是一个2维列向量。这是关于矩阵的一种理解方式。
类似的,在C语言中,我们可以把二维数组看成是一个一维数组,这个一维数组的每一个元素又是一个一维数组。以此类推,一个n维数组可以理解成数据元素为n-1维数组的一维数组。

typedef ElemType Array2[m][n];
等价于:
typedef ElemType Array1[n];
typedef Array1 Array2[m];

这里写图片描述
采用顺序的存储结构表示数组 示意图如下:
左侧是以列序为主序,右侧是以行序为主序。BASIC,C语言和PASCAL都是以行序为主序的存储结构,FORTRAN是以列序为主序的存储结构。这篇博客默认数组采用行序为主序的存储结构。
这里写图片描述

下面介绍称为n维数组的映像函数。
这个函数根据数组下标可以直接计算某一个元素的存储位置。
LOC(j1,j2,...,jn)
=LOC(0,0,...,0)+(b2...bnj1+b3...bnj2+.......+bnjn1+jn)L
=LOC(0,0,...,0)+ni=1ciji
注: LOC(0,0,...,0)L,bi
cn=L,ci1=bicici

这个公式看起来有点复杂,实际上很容易理解,你举个具体的例子,尝试用这个公式算一下,一切都明朗了。

下面就是具体的实现过程
代码写的很简单的(根据这段代码加深下对数组的理解)

#include<stdio.h>
#include<stdlib.h>

#define MAX_ARRAY_DIM 8
typedef int ElemType;
typedef struct {
    ElemType *base; //存储数据
    int dim;
    int *bounds;    //存储每个维度的大小
    int *constants; //存储映射函数中的c_i
} Array;

int InitArray(Array *A,int dim)
{
//一旦建立数组,数组的维数以及各维的长度就确定下来了
    int i;
    int elemtotal=1;
    if(dim<1||dim>MAX_ARRAY_DIM)
        return -1;
    A->dim=dim;
    A->bounds=(int *)malloc(dim*sizeof(int));
    if(!A->bounds)
        exit(-1);
    for(i=0;i<dim;i++)
    {
        scanf("%d",&((A->bounds)[i]));
        if(A->bounds[i]<0)
            return -1;
        elemtotal*=A->bounds[i];
    }
    A->base=(ElemType *)malloc(elemtotal*sizeof(ElemType));
    if(!A->base)
        exit(-1);
    A->constants=(int *)malloc(dim*sizeof(int));
    if(!A->constants)
        exit(-1);
    (A->constants)[dim-1]=1;
    for (i=dim-2;i>=0;i--)
        A->constants[i]=A->bounds[i+1]*A->constants[i+1];
    return 1;
}

int DestoryArray(Array *A)
{
    if(!A->base)
        return -1;
    free(A->base);
    A->base=NULL;
    if(!A->bounds)
        return -1;
    free(A->bounds);
    A->bounds=NULL;
    if(!A->constants)
        return -1;
    free(A->constants);
    A->constants=NULL;
    return 1;
}
int Value(Array A,ElemType *e)
{
    int i,ind;
    int off=0;
    for(i=0;i<A.dim;i++)
    {
        scanf("%d",&ind);
        if(ind<0||ind>A.bounds[i])
            exit(-1);;
        off+=ind*A.constants[i];
    }
    *e=*(A.base+off);   //off是偏移量
    return 1;
}
int Assign(Array *A,ElemType e)
{
    int i,ind;
    int off=0;
    for(i=0;i<A->dim;i++)
    {
        scanf("%d",&ind);
        if(ind<0||ind>A->bounds[i])
            exit(-1);
        off+=ind*A->constants[i];
    }
    *(A->base+off)=e;  //这里指针相加,编译器会自动乘以指向元素的大小
    return 1;
}

void main()
{
    Array A;
    InitArray(&A,3);
    int e=3;
    Assign(&A,e);
    printf("%d",Value(A,&e));
}

2.关于数组的题目

http://www.cnblogs.com/graphics/archive/2010/08/24/1761620.html#link06
这个链接在我的收藏夹里保存了快一年了,之前有次搜东西的时候发现的,排版什么的的看着都很舒服。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值