赞
踩
介绍数组的抽象数据类型
ADT Array{ 数据对象: D={aj1,j2...ji|ji=0,....bi-1,i=1,2,....n,n(>0)是数组的维数,bi是数组第i维的长度} 数据关系: R={R1,R2,....,RN} RI={<aj1,j2,...,aji,j+1,...jn|0<=jk<=bk-1,1<=k<=n且k≠i,0<=j1<=bi-2,i=1,2,...,n} 基本操作: InitArray() 若维数n和各维长度合法,则构造相应的数组A,并返回OK。 DestroyArray(&A) 销毁数组A Value(A,&e,index1,...,indexn) 初始条件:A是n维数组,e为元素变量,随后是n个下标值 操作结果:若各下标不超界,则e赋值为所指定的A的元素值,并返回OK Assign(&A,e,index1,...,indexn) 初始条件:A是n维数组,e为元素变量,随后是n个下标值。 操作结果:若下标不超界,则将e的值赋给所指定的A的元素,并返回OK }ADT Array
两种顺序映像方式:
以行序为主序(低下标优先)
二维数组A中任一元素ai,j 的存储位置
LOC(i,j) = LOC(0,0) + (b2×i+j)×L
以列序为主序(高下标优先)
推广到一般情况,可得到 n 维数组数据元素存储位置的映象关系。
LOC(j1, j2, …, jn ) = LOC(0,0,…,0) + ∑ ci ji
其中 cn = L,ci-1 = bi ×ci , 1 < i <= n
称为 n 维数组的映象函数, 数组元素的存储位置是其下标的线性函数。
假设 m 行 n 列的矩阵含 t 个非零元素,则称
σ=t/(m*n)
为稀疏因子,通常认为 σ<= 0.05 的矩阵为稀疏矩阵。
以常规方法,即以二维数组表示高阶的稀疏矩阵时产生的问题:
三角矩阵
对称矩阵
对角矩阵
非零元在矩阵中随机出现。
//用常规的二维数组表示时的算法
for (col=1; col<=nu; ++col)
for (row=1; row<=mu; ++row)
T[col][row] = M[row][col];
//其时间复杂度为: O(mu×nu)
#define MAXSIZE 12500 typedef struct { int i, j; //该非零元的行下标和列下标 ElemType e; // 该非零元的值 } Triple; // 三元组类型 typedef union { Triple data[MAXSIZE + 1]; int mu, nu, tu; } TSMatrix; // 稀疏矩阵类型 //快速转置算法 Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T){ T.mu = M.nu; T.nu = M.mu; T.tu = M.tu; if (T.tu) { for (col=1; col<=M.nu; ++col) num[col] = 0; for (t=1; t<=M.tu; ++t) ++num[M.data[t].j]; cpot[1] = 1; for (col=2; col<=M.nu; ++col) cpot[col] = cpot[col-1] + num[col-1]; for (p=1; p<=M.tu; ++p) {转置矩阵元素} } // if return OK; } // FastTransposeSMatrix // O(M.nu+M.tu)
广义表是递归定义的线性结构,
LS = ( a1, a2,…, an )
其中:i 或为原子 或为广义表。
例如: A = ( )
F = (d, (e))
D = ((a,(b,c)), F)
C = (A, D, F)
B = (a, B) = (a, (a, (a, … , ) ) )
//广义表的抽象数据类型 ADT Glist { 数据对象:D={ei | i=1,2,..,n; n≥0; ei∈AtomSet 或 ei∈GList, AtomSet为某个数据对象 } 数据关系: LR={<ei-1, ei >| ei-1 ,ei∈D, 2≤i≤n} 基本操作: //结构的创建和销毁 InitGList(&L); DestroyGList(&L); CreateGList(&L, S); CopyGList(&T, L); //状态函数 GListLength(L); GListDepth(L); GListEmpty(L); GetHead(L); GetTail(L); //插入和删除操作 InsertFirst_GL(&L, e); DeleteFirst_GL(&L, &e); //遍历 Traverse_GL(L, Visit()); } ADT Glist
介绍广义表的头尾链表存储表示以及子表分析法存储表示。
长度2,深度3。
内容:介绍广义表的递归操作
一个含直接或间接调用本函数语句的函数被称之为递归函数,它必须满足以下两个条件:
1)在每一次调用自己时,必须是(在某种意义上)更接近于解;
2)必须有一个终止处理或计算的准则。
对于一个输入规模为 n 的函数或问题,用某种方法把输入分割成k (1<k≤n)个子集,从而产生 l 个子问题,分别求解这 l 个问题,得出 l 个问题的子解,再用某种方法把它们组合成原来问题的解。若子问题还相当大,则可以反复使用分治法,直至最后所分得的子问题足够小,以至可以直接求解为止。
在利用分治法求解时,所得子问题的类型常常和原问题相同,因而很自然地导致递归求解。
广义表从结构上可以分解成
广义表 = 表头 + 表尾
或者
广义表 = 子表1 + 子表2 + ··· + 子表n
因此常利用分治法求解之。
算法设计中的关键问题是,如何将 l 个子问题的解组合成原问题的解。
将广义表分解成 n 个子表,分别(递归)求得每个子表的深度,
广义表的深度=Max {子表的深度} +1
可以直接求解的两种简单情况为:
空表的深度 = 1
原子的深度 = 0
/* 广义表的深度=Max {子表的深度} +1 空表的深度 = 1, 原子的深度 = 0 例:D=( A,B,C )=( ( ),(e),(a,(b,c,d))) DEPTH(D)=1+MAX{ DEPTH(A),DEPTH(B),DEPTH(C)} DEPTH(C)=1+MAX{ DEPTH(a),DEPTH((b,c,d))}=2 DEPTH(D)=1+MAX{ 1,1,2}=3 */ typedef enum {ATOM, LIST} ElemTag; // ATOM==0:原子, LIST==1:子表 typedef struct GLNode { ElemTag tag; // 标志域 union{ AtomType atom; // 原子结点的数据域 struct {struct GLNode *hp, *tp;} ptr; }; } *GList int GlistDepth(Glist L) { // 返回指针L所指的广义表的深度 if (!L) return 1; if (L->tag == ATOM) return 0; for (max=0, pp=L; pp; pp=pp->ptr.tp){ dep = GlistDepth(pp->ptr.hp); if (dep > max) max = dep; } return max + 1; } // GlistDepth
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。