数据结构第四章
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第四章数组和串
数组
数组的定义及其基本操作
数组的存贮结构
特殊矩阵的压缩存储
稀疏矩阵的压缩存储
数组的定义及其基本操作
数组的定义:数组(Array):是n(n>1)个相同类型的数据元素a0 , a1 , …,an-1构成的有限序列,且该有限序列存储在块地址连续的内存单元中。(即物理存储与逻辑结构相一致)•数组中的数据元素数目固定。
•数组中的每个数据元素具有相同的数据类型。
•数组中的每个数据元素都和一组唯一的下标值相对应。
•数组是一种随机存储结构,可随机存取数组中的任意数据元素。
•地址计算:一维数组同线性表相同;
计算公式:Loc(ai) = Loc(a0) + i*k (0<= i 注:Loc(a0) 是a0元素的地址,Loc(ai)是ai元素的地址,k是每个元素所占的存储单元数。 二维数组 设m行n列的二维数组Am*n,有 地址计算: 1、按行序列序计算: Loc( aij)=Loc(a11)+[(i-1)n+(j-1)]*l 注:k是每个元素所占的单元数。 2、按列序序列计算: Loc(aij)=Loc(a11)+[(j-1)m+(i-1)]*l 数组的基本操作 1. arraylength(D) 2. Storage(D, i, x) 3. Get(D, i, x) 数组的存储结构 数组一般在计算机中采用线性结构存储,对于一维数组同线性表相同;关于二维数组和多维数组,一般语言中采用行序列序,即先存第一(或零)行,然后第二行依次存储。 数组也允许有两种存储分配方法:静态和动态。 •静态数组:运行期间数组大小不能改变,需预先给出。 •动态数组:可以动态建立和动态撤消的数组。 动态数组: 一维动态数组 int *a; a=(int *)malloc(n*sizeof(int)); a[0]…a[n-1] free(a); 二维动态数组 int **a,i; a=(int **)malloc(row *sizeof(int *)); for (i=0;i a[i]=(int *)malloc(col*sizeof(int)); 释放空间free(a)? for(i=0;i free(a[i]); free(a); 特殊矩阵的压缩存储 *特殊矩阵 1、对称矩阵的压缩存储 对称矩阵 •定义:设n 阶方阵中的元素关于主对角线对称,即满足条件:aij = aji 1<=i , j <=n, 这样的方阵称为n阶对称方阵。 •存储方法:只存储矩阵中上三角或下三角中的元素,这样可以将n2个元素压缩存储到n(n+1)/2个元素。即用一维数组a[n*(n+1)/2]来存储该矩阵,一维数组中的元素同二维数组.元素的对应关系: i(i-1)/2+j-1 当 i>=j 时 k= j(j-1)/2+i-1 当 j>i 时 则[n(n+1)/2]为n 阶对称方阵的压缩存储(下三角存储即用行序列序)。 2、 n 阶下三角矩阵 3、对角矩阵 Loc(aij)=Loc(a11)+2(i-1)+(j-1) 4、稀疏矩阵的压缩存储 定义:非零元较零元少,且分布没有一定规律的矩阵 假设在m*n 的矩阵中,有t 个元素不为零,令 ,称 为矩阵的稀疏因子。通常认为 ≤0.05时称为稀疏矩阵。 稀疏矩阵M 和T M 由{(1,2,12), (1,3,9), (3,1,-3), (3,6,14), (4,3,24), (5,2,18), (6,1,15), (6,4,-7) } 和矩阵维数(6,7)唯一确定 n m t *=δδδ *压缩储存 稀疏矩阵的压缩存储方法是只存非零元素,但由于稀疏矩阵元素中的非零元素是没有规律的,所以在存储时还必须存储每个元素的行下标和列下标值。这样稀疏矩阵中的每一个非零元素需由一个三元组(i,j,aij)唯一确定。 稀疏矩阵的压缩存储方法:链式存储结构——三元组十字链表 稀疏矩阵的三元组也可采用链式存储结构。单链表结构, 缺点:操作复杂度高——由链表的非随机存取特性限定的。 十字链表 *设行指针数组和列指针数组,分别指向每行、列第一个非零元 *结点定义 typedef struct node { int row,col,val; struct node *down, *right; }JD; 从键盘接收信息建立十字链表算法 1、初始化头指针向量 2、初始化各行列链表 3、动态生成结点,输入非零元 4、将结点插入行 5、将结点插入列 Status CreateSMatrix_OL(CrossList &M) { //创建稀疏矩阵M。采用十字链表存储表示 if (M) free(M); { scanf(&m,&n,&t); //输入M的行数、列数和非零元个数 M.mu=m; M.nu=n; M.tu=t; if (!(M.rhead=(Olink *) malloc ((m+1)*sizeof(Olink)))) exit (overflow); if (!(M.chead=(Olink *) malloc ((n+1)*sizeof(Olink)))) exit (overflow); M.rhead[ ]=M.chead[ ]=NULL; //初始化行列头指针向量; //各行列链表为空链表 for (scanf(&i,&j,&e); i!=0;scanf(&i,&j,&e)) { //按任意次序输入非零元 if (!(p=(OLNode *) malloc (sizeof(OLNode)))) exit (overflow); p->I=I; p->j=j; p->e=e; //生成结点 If (M.rhead[I]==NULL || M.rhead[I]->j>j) { p->right=M.rhead[I];M.rhead[I]=p; } Else { //寻查在行表中的插入位置 for (q=M.rhead[I]; (q->right)&&q->right->j {p->right=q->right; q->right=p;} } //完成行插入 If (M.chead[j]==NULL || M.chead[j]->i>i) { p->down=M.chead[j];M.chead[j]=p; } Else { //寻查在列表中的插入位置 for (q=M.chead[j]; (q->down)&&q->down->idown) p->down=q->down; q->down=p; } //完成列插入 }//for } //if Return OK; }//CreateSMatrix_OL