前言:  

  2、3、4章讨论的线性结构中的数据元素都是非结构的原子类型,元素的值是不再分解的。本章讨论的两种数据结构---数组和广义表可以看成是线性表在下述含以上的扩展:表中的数据元素本身也是一个数据结构。

  其中、数组是一种比较熟知的数据类型,几乎所有程序语言都把数组类型设定为固有类型,前两节节以抽象数据类型的形式讨论数组的定义和实现,使读者加深对数组的理解。  

目录:

  1.数组的定义

  2.数组的顺序表示和实现

  3.矩阵的压缩存储

  4.广义表的定义

  5.广义表的存储结构

  6.m元多项式的表示

  7.广义表的递归算法    

正文:

  一、数组的定义

    类似于线性表,抽象数据类型数组可形式地定义为:

    ADT  Array{

      数据对象:

            ji=0,... ,bi-1, i=1,2,...,n

            D={aj1 j2 ... jn | n(>0) 称为数组的维数,bi 是数组第 i 维的长度,ji 是数组元素的第 i 维下标, aj1 j2 ... jn ∈ElmeSet}

      数据关系:

            R={R1,R2...Rn}

            Ri={

                < aj1 ... ji ... jn ,aj1 ... ji+1 ... jn  > |

                  0<= j<=bk-1,1<= k <=n 且 k <> i

                  0<= j<=bk-2,

                  aj1 ... ji ... jn ,aj1 ... ji+1 ... jn ∈ D ,i = 2 ,  ...  n

              }

      基本操作:

            InitArray();

            DestoryArray();

            Value();

            Assign();

    }ADT   Array;

  二、数组的顺序表示及实现

    由于数组一般不作插入和删除操作,也就是说,一旦建立了数组,则结构中的数据元素和元素之间的关系就不再变动。因此,采用顺序存储结构表示数组是自然而然的事了

    由于存储单元是一维的结构,而数组是多维的结构,则用一组连续的存储单元存放数组的数据元素有个次序问题。

    例如、对于二维数组来说,可以看成是一维数组,一维数组的每一个数组元素又是一个一维数组。对应的对于二维数组有两种存储方式:

      1.以列序为主序的存储方式

      2.以行序为主序的存储方式

      

    由此,对于数组,一旦规定了他的维度和各维度的长度,便可为它分配存储空间。反之,至于给出一组下标便可求出相应数组元素的存储位置。

    大部分程序设计语言都采用了以行序为主序的存储方式。以下采用以行序为主序的存储方式为例予以说明

      假设每个数据元素占L个存储单元,则二维数组A 中任一元素 aij 的存储位置可由下式确定:

      LOC(i , j) =  LOC(0,0) + (b2 * i +j )*L

      LOC(i , j)是 a ij 的存储位置, LOC(0,0) 是a00 的存储位置,即二维数组A 的起始存储位置,也称基址,基地址。

    将其推广到一般,得n 维数组的数据元素存储位置的公式为:

      LOC(j1, ...jn) = LOC(0,...0) + (b2*b3*...*bn*j1+ b3*b4*...*bn*j2+  ...  + bn*jn-1 + jn) * L

      =LOC(0,...0) + ∑ ci ji  其中 cn=L , ci-1 = bi * ci  ,1< i <n

    LOC(0,...0) + ∑ ci ji 称为 n维数组的映像函数。一旦确定了数组的各维长度,ci 就是一个常数。

    数组的顺序存储结构:

typedef struct{ElemType *base;                 //数组元素基址,由InitArray 分配int dim;                        //数组维数int *bounds;                    //数组维界基址,由InitArray 分配int *constants;                 //数组映像函数常量基址,由InitArray 分配(constants[i]=ci)
}Array;

    代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
//stdarg.h 头文件定义了一个变量类型 va_list 和三个宏,
//这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数。#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define UNDERFLOW -3#define MAX_ARRAY_DIM 8
//Status是函数的类型,其值是函数结果状态码
typedef int Status;
typedef char ElemType;typedef struct{ElemType *base;                 //数组元素基址,由InitArray 分配int dim;                        //数组维数int *bounds;                    //数组维界基址,由InitArray 分配int *constants;                 //数组映像函数常量基址,由InitArray 分配(constants[i]=ci)
}Array;//初始化数组A]
Status InitArray(Array &A,int dim,...){if(dim<1||dim>MAX_ARRAY_DIM)return ERROR;A.dim=dim;A.bounds=(int *)malloc(dim*sizeof(int));if(!A.bounds) exit(OVERFLOW);//初始化每一维度的长度,并计算总的元素个数int ElemTotal=1;va_list ap;va_start(ap, dim);for(int i=0;i<dim;i++){A.bounds[i]=va_arg(ap, int);                //依次接收dim 参数后面的未确定的参数if(A.bounds[i]<0) return UNDERFLOW;ElemTotal *= A.bounds[i];                    //计算元素总数( 累乘维度 )
    }va_end(ap);//为dim 维数组A 分配所有的存储空间A.base=(ElemType *)malloc(ElemTotal*sizeof(ElemType));if(!A.base) exit(OVERFLOW);A.constants=(int *)malloc(dim*sizeof(int));if(!A.constants) exit(OVERFLOW);A.constants[dim-1]=sizeof(ElemType);for(int j=dim-2;j>=0;j--){A.constants[j]=A.bounds[j+1]*A.constants[j+1];}    return OK;
}Status DestoryArray(Array &A){//销毁数组Aif(!A.base) return ERROR;free(A.base);A.base=NULL;if(!A.bounds) return ERROR;free(A.bounds);A.bounds=NULL;if(!A.constants) return ERROR;free(A.constants);A.constants=NULL;return OK;
}//计算 元素在 A 的相对位置,并用off返回
Status LocateArray(Array &A,va_list ap,int &off){off=0;for(int i=0;i<A.dim;i++){int locate=va_arg(ap, int);if(locate<0||locate>A.bounds[i])return OVERFLOW;off+=A.constants[i]*locate;}return OK;
}//返回某个合法下标对应的值。
Status Value(Array &A,ElemType *e,...){va_list ap;va_start(ap,e);int off;LocateArray(A,ap,off);va_end(ap);    *e=*(A.base+off);return OK;
}//给A数组的合法下标赋值
Status Assign(Array &A,ElemType e,...){va_list ap;va_start(ap, e);int off;LocateArray(A,ap,off);va_end(ap);    *(A.base+off)=e;return OK;
}void main(){Array A;InitArray(A,4,3,4,5,6);//赋值Assign(A,'b',2,1,4,1);ElemType e;//取值Value(A,&e,2,1,4,1);printf("value:%c\n",e);
}

转载于:https://www.cnblogs.com/ahguSH/p/6237689.html

第五章:1.数组和广义表 -- 数组相关推荐

  1. 算法与数据结构 --- 串,数组与广义表 --- 数组

    第一部分 --- 数组的定义 1.二维数组可以理解为一维数组的堆叠 2.二维数组既可以看作一个线性结构,也可以看作是一个非线性结构,所以我们将二维数组看作是一个特殊的线性结构,它是线性结构的拓展 (线 ...

  2. 数据结构05数组和广义表

    第五章 数组 和 广义表 数组和广义表可以看成是线性表在下述含义上的扩展:表中的数据元素本身也是一个数据结构. 5.1 数组的定义 n维数组中每个元素都受着n个关系的约束,每个元素都有一个直接后继元素 ...

  3. C语言数据结构学习——数组和广义表

    数组和广义表 数组 数组定义 特点 常见运算及声明方式 数组的顺序表示和实现 矩阵的压缩存储 概念 稀疏矩阵 对称矩阵 三角矩阵 广义表 数组 数组定义 数组(Array)是有序的元素序列.若将有限个 ...

  4. 数据结构 习题 第五章 多维数组和广义表 (C语言描述)

    最近在复习数据结构,所以想把平时上课做的习题做个总结,如果大家有遇到这方面的问题就可以参考一下了,废话不多说,直接开始吧. 1.单选题 稀疏矩阵一般的压缩存储方法有两种,即( D) A. 二维数组和三 ...

  5. 【课上笔记】第五章 数组和广义表

    数组和广义表 5.1多维数组 5.1.1数组的逻辑结构 数组是我们熟悉的一种数据结构,可以看作线性表的推广. 数组作为一种数据结构其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一类型.比如 ...

  6. 【数据结构总结】第四章:串、数组和广义表(线性结构)

    第四章:串.数组和广义表(线性结构) 提示:本文主要是以思维导图的形式概括数据结构第一章的精华内容,基本不会用到文字性的内容,目的是为了给大家梳理每个重要的知识点的相关概念,方便大家在复盘的时候快速阅 ...

  7. 《数据结构》-第四章 串、数组和广义表(习题)

    第四章 串.数组和广义表练习题 本章考点较少易于掌握,对于串的重点考点为串的模式匹配算法:数组的主要考点为数组下标与存储地址计算和特殊矩阵的压缩存储方法:针对广义表的考点主要为在广义表中取原子项(表) ...

  8. 数据结构(C语言第2版) 课后习题答案之第四章 串、数组和广义表

    目录 第4章  串.数组和广义表 1.选择题 (1)串是一种特殊的线性表,其特殊性体现在(  ). (2)串下面关于串的的叙述中,(  )是不正确的? (3)串"ababaaababaa&q ...

  9. 数组和广义表 - [数据结构]

    2005-09-07 数组和广义表 - [数据结构] 第五章 数组和广义表 --非线性数据结构 5.1 数组的定义和运算 ☆二维数组的逻辑结构形式定义为: 2_Array=( D, R ) 其中 D= ...

最新文章

  1. java switch 表达式_尝鲜Java 12新特性:switch表达式
  2. ClickHouse系列教程六:源码分析之Debug编译运行
  3. python文件中环境声明_Python环境构建
  4. 2018年 第09届 蓝桥杯 Java B组 决赛真题详解及小结
  5. 你知道css单位fr吗?
  6. python的read函数_Python Pandas pandas.read_sql函数方法的使用
  7. 又拍云php表单,又拍云的表单api提交
  8. mysql索引背后的数据结构_MySQL索引背后的数据结构及算法原理
  9. Exynos4412 BSP平台搭建(详细图解)
  10. 相机模型与标定(十一)--LMEDS,M估计,RANSAC估计对比
  11. 初学51单片机--网上教程(51自学网)
  12. 「数据科学」数据科学家为什么该学习PostgreSQL
  13. 加快C++代码的编译速度方法
  14. 神器Android键值数据库MMKV——基于 mmap 的高性能通用 key-value 组件
  15. SRM 615 D1L2: LongLongTripDiv1
  16. 服务器数据防泄漏,深信达-MCK
  17. 小啊呜产品读书笔记001:《邱岳的产品手记-10》第19讲 产品经理如何与开发打交道(上):打破思维的边界 第20讲 产品经理如何与开发打交道(下):合作与共赢
  18. 这款工具可以直接把Office干得稀碎
  19. aliyun 的云监控实践
  20. 基于VS 2005环境的MS office自动化开发之熟悉环境篇

热门文章

  1. 算法图解学习笔记01之二分查找
  2. 通向财务自由之路07_利用方案设法启动你的系统
  3. ios 画带有箭头的线_ios纯色箭头与渐变色箭头的实现
  4. BlazeDS4 添加MSSQL/MySQL数据源
  5. EditPlus配置Python环境
  6. 使用计算机在什么上传输,MODEM的作用是使计算机数据能在什么上传输
  7. android mediarecorder 输出到流_音视频的采集、编码、封包成 mp4 输出
  8. ios 自动打包命令_通过命令行xcodebuild编译打包iOS应用
  9. 微服务 注册中心的作用_SpringCloud(二)服务注册中心与Eureka工作原理介绍
  10. python爬取邮件内容_登陆邮箱 爬取邮件