数据结构组广义表

合集下载

数据结构 5数组和广义表A

数据结构 5数组和广义表A
12
1 Status Locate(Array A,va_list ap,int &off) 2{ 3 //若ap指示的各下标值合法,则求出该元素在A中,相对地
址off
4 off=0; 5 for(i=0;i<A.dim;++i) 6 { 7 ind=va_arg(ap,int); 8 if(ind<0||ind>A.bounds[i]) return OVERFLOW; 9 off+=A.constants[i] *ind; 10 } 11 return OK; 12 }
行数 总列数,即 第2维长度 元素个数
ij
补充:计算二维数组元素地址的通式
设一般的二维数组是A[c1..d1, c2..d2],这里c1,c2不一定是0。
单个元素 长度
二维数组列优先存储的通式为: LOC(aij)=LOC(ac1,c2)+[(j-c2)*(d1-c1+1)+i-c1)]*L
6
例1〖软考题〗:一个二维数组A[1..6, 0..7],每个数组元素
16
5.4
1、定义:
广义表的定义
广义表是线性表的推广,也称为列表(lists) 记为: LS = ( a1 , a2 , ……, an ) 广义表名 表头(Head) 表尾 (Tail) n是表长
在广义表中约定:
① 第一个元素是表头,而其余元素组成的表称为表尾; ② 用小写字母表示原子类型,用大写字母表示列表。
13
1 Status Value(Array A,ElemType &e,…){ 2 //A是n维数组,e为元素变量,随后是n个下标值,若各下
标不超界,则e赋值为所指定的A的元素值,即将指定元素值 读到e变量中。

数据结构-第五章 数组与广义表-文档资料

数据结构-第五章 数组与广义表-文档资料

上 三 角 矩 阵 下 三 角 矩 阵
a00 a10 a 20 an10
0 1 2
a01 a11 a21 an11
3 4
a02 a12 a22 an12
5

6 7
a0 n1 a1n1 a2 n1 an1n1
行 列 值 (row) (col) (value) 0 4 91 1 1 11 2 5 28 3 0 22 3 2 -6 5 1 17 5 3 39 6 0 16
用三元组表表示的稀疏矩阵及其转置
行 列 值 (row) (col) (value) 0 3 22 0 6 15 1 1 11 1 5 17 2 3 -6 3 5 39 4 0 91 5 2 28 行 列 值 (row) (col) (value) 0 4 91 1 1 11 2 5 28 3 0 22 3 2 -6 5 1 17 5 3 39 6 0 16
4 5 6 7 8 9 10
B a00 a01 a10 a11 a12 a21 a22 a23 … an-1n-2 an-1n-1
三对角矩阵中除主对角线及在主对角线上 下最临 近的两条对角线上的元素外,所有其它元素均为 0。总共有3n-2个非零元素。 将三对角矩阵A中三条对角线上的元素按行存放在 一维数组 B 中,且a00存放于B[0]。 在三条对角线上的元素aij 满足 0 i n-1, i-1 j i+1 在一维数组 B 中 A[i][j] 在第 i 行,它前面有 3*i-1 个非零元素, 在本行中第 j 列前面有 j-i+1 个,所 以元素 A[i][j] 在 B 中位置为 k = 2*i + j。
三对角矩阵的压缩存储

数据结构-广义线性表广义表

数据结构-广义线性表广义表
template <class T> class Lists { public: Lists( ) ; Lists(Lists ls1, Lists ls2); ~Lists( ); int Length( ); int Depth(GLNode<T> *ls); GLNode *Head( ); GLNode *Tail( ); private: GLNode<T> *ls; };
清华大学出版社
数据结构( 数据结构(C++版) 版
广义线性表——广义表 广义线性表——广义表 ——
广义表的示例 AБайду номын сангаас=( ) B =(e) C =(a, (b,c,d)) , , D =(A, B, C) E =(a, E) F =(( ))
长度?深度?表头?表尾? 长度?深度?表头?表尾?
清华大学出版社
数据结构( 数据结构(C++版) 版
广 义 表 类 的 声 明
清华大学出版社
广义线性表——广义表 广义线性表——广义表 ——
数据结构( 数据结构(C++版) 版
广义表的操作——建立广义表 建立广义表 广义表的操作 template <class T> Lists::Lists(Lists ls1,Lists ls2) { ls = new GLNode ls->tag = 1; ls->ptr.hp = ls1; ls->ptr.tp = ls2; }

C
1 0 a
1 1 0 b
1 0 c
1

0 d
清华大学出版社
广义线性表——广义表 广义线性表——广义表 ——

数据结构广义表

数据结构广义表

结点结构是无论什么结点都有三个域:
第一个域是结点类型标志tag; 第二个域是指向一个列表的指针(当tag=1时) 或一个原子(当tag=0时); 第三个域是指向下一个结点的指针tp。
3 广义表的存储结构
形式描述为:
typedef enum{ ATOM, LIST }ElemTag typedef struct GLNode { //定义广义表结点 ElemTage tag; //公共部分,用以区分 原子结点和表结点 Unin{ //原子结点和表结点的联合部分 AtomType atom;//原子类型结点域, // AtomType由用户定义 struct GLNode *hp,; //表结点的表头指针域 }; struct GLNode *tp; //指向下一个结点的指针 }*Glist; //广义表类型
5. E=(a,E)
这是一个递归列表,其元素中有自己。
广义表也可以用图形表示,例如前述的广义表D和E可表示为:
广义表D
D
广义表E
E
C
A
B
a
e
a b c d
2 广义表的基本运算
广义表的基本运算 ⑴ 取表头 HEAD(LS); ⑵ 取表尾 TAIL(LS)。
3 广义表的存储结构
广义表中的数据元素可以是单元素,或是广义表, •很难用顺序存储结构表示,常采用链式存储结构。 1.表头表尾链存储结构 有两类结点:表结点和单元素结点。
P 1 3 1 1
A=y((c,3),(D,2)) C=x((1,10),(2,6))

1 2
A
z y 1 1 1 3
C
x 0 0 15 ^
B
1 2
1 2

数据结构-广义表

数据结构-广义表

数据结构-⼴义表⼴义表简称表,是线性表的推⼴,表中元素可以是数据元素(原⼦),也可以是⼦表。

⼴义表的表头(head)是表中第⼀个表元素、表尾(tail)是除了表头外其它元素组成的表。

⾸先要对⼴义表结点类GenListNode和返还值的结构类Item进⾏定义。

它们都有⼀个⽤来标明结点类型的标志域utype、⼀个信息域info。

此外,⼴义表结点类还多了⼀个尾指针tlink指向下⼀个结点。

utype为0时为⼴义表专⽤的附加头结点,info存放引⽤计数refutype为1时为原⼦结点、info存放数据值valueutype为2时为⼦表结点,info存放指向⼦表表头的指针hlink这种存储表⽰中,⼴义表中的所有表,⽆论是哪⼀层的⼦表,都带有⼀个附加头结点,空表也不例外所有位于同⼀层的表元素,在其存储表⽰中也在同⼀层最⾼⼀层的表结点个数(除附加头结点外)即为表的长度#include <iostream>#include <assert.h>#include <stdlib.h>using namespace std;template <class T>struct Items{ //返回值的类结构定义int utype; //标志域union{int ref; //utype=0,存放引⽤计数T value; //utype=1,存放数值GenListNode<T> *hlink; //utype=2.存放指向⼦表的指针} info;Items():utype(0),info.ref(0){} //构造函数Items(Items<T>& RL){utype=RL.utype;info=;} //复制构造函数}template <class T>struct GenListNode{ //⼴义表结点类定义public:GenListNode():utype(0),tlink(NULL),info.ref(0){}GenListNode(GenListNode<T>& RL){utype=RL.utype;tlink=Rl.tlink;info=;}private:int utype;GenListNode<T> *tlink; //⽐返回值的类结构多了⼀个tlink指针union{int ref;T value;GenListNode<T> *tlink;} info;}template <class T>class Genlist{public:Genlist();~Genlist();bool Head(Items& x);bool Tail(Genlist<T>& It);GenListNode<T> *First();GenListNode<T> *Next(GenListNode<T> *elem);void Copy(const Genlist<T>& R);int Length();int depth();friend istream& operator>>(istream& in,Genlist<T>& L);private:GenListNode<T> *first; //⼴义表头指针GenListNode<T> *Copy(GenListNode<T> *ls);int Length(GenListNode<T> *ls);int depth(GenListNode<T> *ls);bool equal(GenListNode<T> *s,GenListNode<T> *t); //判断s和t为表头的两个表是否相等void Remove(GenListNode<T> *ls);void Createlist(istream& in,GenListNode<T> *&ls);}template <class T>Genlist<T>::Genlist(){ //构造函数first=new GenlistNode;assert(first!=NULL);}//Head⽅法返回bool值,通过引⽤变量x返回是⼴义表第⼀个元素(Item类型的对象);template <class T>bool Genlist<T>::Head(Items<T>& x){//若⼴义表⾮空,则通过x返回其第⼀个元素的值,否则函数没有意义if(first->tlink==NULL) return false;else{x.utype=first->tlink->utype;=first->tlink->info;return true;}}template <class T>bool Genlist<T>::Tail(Genlist<T>& It){//若⼴义表⾮空,则通过It返回⼴义表除表头元素以外其他元素组成的表,否则函数没有意义if(first->tlink==NULL) return false;else{It.first->utype=0;It.first->info.ref=0;It.first->tlink=Copy(first->tlink->tlink);return true;}}//First⽅法返回的是指向⼴义表第⼀个元素(GenlistNode类型的对象)的指针template <class T>GenlistNode<T> *Genlist<T>::First(){if(first->tlink==NULL)return NULL;else return first->tlink;}template <class T>GenlistNode<T> *Genlist<T>::Next(GenlistNode<T> *elem){ //返回表元素elem的直接后继元素if(elem->tlink==NULL) return NULL;else return elem->tlink;}⼴义表的遍历可以⽤如下⽅法:template <class T>struct Items {int mark;int utype;union{char *LName; //附加头结点的info域改为了表名T value;GenListNode<T> *hlink;}info;Items():mark(0),utype(0),info.LName('\0'){}Items(Items<T>& RL){mark=Rl.mark;utype=RL.utypr;info=;}}template <class T>struct GenListNode {public:GenListNode():mark(0),utype(0),tlink(NULL),info.LName('\0'){}GenListNode(GenListNode<T>& RL){mark=RL.mark; utype=RL.utype; tlink=RL.tlink; info=;} int getMark(GenListNode<T> *elem){return elem->mark;}int getType(GenListNode<T> *elem){return elem->utype;}int getListName(GenListNode<T> *elem){return elem->info.LName;}T getValue(GenListNode<T>* elem){return elem->info.value;}GenListNode* gettlink(GenListNode<T>* elem){return elem->tlink;}GenListNode* gethlink(GenListNode<T>* elem){return elem->info.hlink;}private:int mark;int utype;GenListNode<T> *tlink;union{char *LName;T value;GenListNode<T> *hlink;}info;}template GenList{public:GenList();~GenList(){Remove(first);}bool Head(Items& x);bool Tail(GenList<T> &lt);GenListNode<T> *First(){return first;}GenListNode<T> *Next(GenListNode<T> *elem){return elem->tlink;} void Traverse(); //⾮递归遍历private:GenListNode<T> *first;void Traverse(GenListNode<T> *ls); //递归遍历}template <class T>void GenList::Traverse(){Stack<GenListNode<T>*> st;GenListNode<T> *ls=first;while (ls!=NULL) {ls->mark=1;if (ls->utype==2){ //⼦表结点if (ls->info.hlink->mark==0){st.Push(ls->tlink;) //暂时先把⼦表结点的右结点⼊栈ls=ls->hlink;}else { //⼦表已经遍历过cout<<ls->info.hlink->info.LName;if(ls->tlink!=NULL){cout<<',';ls=ls->tlink;}}}else {if (ls->utype==0) cout<<ls->info.LName<<'('; //表头结点else if (ls->utype==1){ //原⼦结点cout<<ls->info.value;if(ls->tlink!=NULL) cout<<',';}if(ls->tlink==NULL){cout<<')';if(!st.isEmpty()){st.Pop(ls);if(ls!=NULL) cout<<',';else cout<<')';}}else ls=ls->tlink;}}}template <class T>void GenList::Traverse(GenListNode<T> *ls){if(ls!=NULL){ls->mark=1;if (ls->utype==0) cout<<ls->info.LName<<'('; //表头结点else if (ls->utype==1) { //原⼦结点cout<<ls->info.value;if (ls->tlink!=NULL) cout<<',';}else if (ls->utype==2) { //⼦表结点if (ls->info.hlink->mark==0) Traverse(ls->info.hlink);else cout<<ls->info.hlink->info.LName; //⼦表已经遍历过if (ls->tlink!=NULL) cout<<',';}Traverse(ls->tlink);}else cout<<')';}。

数据结构广义表

数据结构广义表

{ printf("("); /*输出'('*/
if (g->val.sublist==NULL) printf(""); /*输出空子表*/
else DispGL(g->val.sublist); /*递归输出子表*/
}
else printf("%c", g->val.data); /*为原子时输出元素值*/
假如把每个表旳名字(若有旳话)写在其表旳前面,则 上面旳5个广义表可相应地体现如下:
A()
B(e)
C(a,(b,c,d))
D(A(),B(e),C(a,(b,c,d)))
E((a,(a,b),((a,b),c)))
若用圆圈和方框分别体现表和单元素,并用线段把表 和它旳元素(元素结点应在其表结点旳下方)连接起来,则 可得到一种广义表旳图形体现。例如,上面五个广义表 旳图形体现如下图所示。
A() B(e) C(a,(b,c,d)) D(A(),B(e),C(a,(b,c,d))) E((a,(a,b),((a,b),c)))
AB e
C A
a b cd
D BC
ea b cd
E
a
ab
c
ab
8.2 广义表旳存储构造
广义表是一种递归旳数据构造,所以极 难为每个广义表分配固定大小旳存储空间,所
GLNode *CreatGL(char *&s)
{ GLNode *h;char ch=*s++; /*取一种扫描字符*/
if (ch!='\0')
/*串未结束判断*/
{ h=(GLNode *)malloc(sizeof(GLNode));/*创建新结点*/

数据结构第06章广义表

数据结构第06章广义表

第6章广义表z6.1 广义表的基本概念z6.2 广义表的存储结构z6.3 广义表的操作算法16.1 广义表的基本概念广义表(列表)的概念-n( ≥0 )个表元素组成的有限序列,记作LS= ( a1, a1, a2, …, a n)LS是表名,a i是表元素,它可以是单个元素(称为原子) ,可以是表(称为子表) 。

n为表的长度。

n= 0 的广义表为空表。

n> 0时,表的第一个表元素称为广义表的表头(head),除此之外,其它表元素组成的表称为广义表的表尾(tail)。

2广义表举例:(1)A=()(2)B=(e)(3)C=(a, (b, c, d) )(4)D=(A,B,C)(5)E= (a , E)9任意一个非空广义表,均可分解为表头和表尾。

9对于一个非空广义表,其表头可能是原子,也可能是子表;而表尾一定是子表。

3广义表的基本操作:•结构的创建和销毁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());66. 2 广义表的存储结构z由于广义表中的元素不是同一类型,因此难以用顺序结构表示,通常采用链接存储方法存储广义表,并称之为广义链表。

z由于广义表中有两种数据元素,原子或子表,因此,需要两种结构的结点:一种是表结点,一种是原子结点。

z下面介绍一种广义表的链式存储结构。

78扩展的线性链表表示法:-子表结点由三个域组成:标志域、表头指针域和指向下一个元素的指针域;-原子结点的三个域为:标志域、值域和指向下一个元素的指针域。

数据结构广义表

数据结构广义表
}GLNode2;
22
创建广义表
创建广义表就是按照所给的表示具体广义表的字符串 str创建一个广义表h。
和头链和尾链存储结构广义表的创建算法类同,原子 和子表存储结构的创建广义表操作同样可以分解为创建 表头广义表和创建表尾广义表。
把表示广义表的字符串str分解成表头字符串hstr和表 尾字符串str的函数DecomposeStr(str, hstr)设计和前面的 方法完全相同。
{ for(j = 0; j < i-1; j++) hstr[j] = str[j+1];
hstr[j] = '\0';
if(str[i] == ',') i++;
str[0] = '(';
for(j = 1; i <= n-2; i++, j++) str[j] = str[i];
str[j] = ')';
这样,还需要设计一个把表示广义表的字符串str分解 成表头字符串hstr和表尾字符串str的函数 DecomposeStr(str, hstr)。
14
void DecomposeStr(char str[], char hstr[])
{ int i, j, tag, n = strlen(str);
pre = h; for(max = 0; pre != NULL; pre = pre->val.subList.tail) { dep = GListDepth(pre->val.subList.head);
if(dep > max) max = dep; } return max + 1; }

第5章 数据结构 多维数组和广义表

第5章 数据结构 多维数组和广义表

按列优先存储的寻址方法与此类似。
数据结构(C版)
广义线性表——多维数组
数组的存储结构与寻址——多维数组
n(n>2)维 数组一般也采用 按行优先和按列 优先两种存储方 法。请自行推导 任一元素存储地 址的计算方法。 Loc(aijk ) = Loc(a000) +( i×m2×m3 + j×m3 + k )×c
如何压缩存储?
只存储上三角(或下三角)部分的元素。
数据结构(C版)
a00 a10 a 20 a30
a01 a11 a21 a31
a02 a12 a22 a32
a03 a13 a23 a33
上 三 角 矩 阵
a00 a01 a02 a10 a11 a12 a a a 20 21 22
(a) 三对角矩阵
按行 存储
元素aij在一维数组中的序号 =2 + 3(i-1)+( j-i + 1)+1 =2i+ j+1 ∵一维数组下标从0开始 ∴元素aij在一维数组中的下标 =2i+ j (b) 寻址的计算方法
0
1
2
3
4
5
6
7
8
9 10
11 12
a00 a01 a10 a11 a12 a21 a22 a23 a32 a33 a34 a43 a44
数组——线性表的推广
a11 a21 … am1 a12 a22 … am2 … … … … a1n a2n … amn
A=(A1,A2,……,An)
其中: Ai=(a1i,a2i,……,ami) (1≤i≤n)
A=
二维数组是数据元素为线性表的线性表。

数据结构第5章数组和广义表2广义表ppt课件PPT精品文档33页

数据结构第5章数组和广义表2广义表ppt课件PPT精品文档33页
所以在对应的存储结构中,其存储结点也有相应划分。 对于原子结点,应包含值域; 对于表结点,应包含指示表头的表头指针域(指向
表中的第一个元素)和指示表尾的表尾指针域(指向除 去原表头元素后的广义表)。
4)D=( A , B ,C )
n=3,3个元素都是子表
5)E=(a, E)
n=2,a 为原子,E为子表
D=(A,B,C)=(( ),(e),(a,(b,c,d))),共享表
E=(a,E)=(a,(a,E))= (a,(a,(a,…….))),E为递归表
§5.4 广义表的类型定义
❖试用图形表示下列广义表
§5.4 广义表的类型定义 ❖广义表的特点
▪ 可共享
广义表的元素可以为其他广义表所共享 A = ( a , B ) =( a , ( b , c , d ) )
§5.4 广义表的类型定义
❖例1:求下列广义表的长度
1)A =( )
n=0,因为A是空表
2)B = ( e )
n=1,表中元素e是原子
3)C =( a ,( b , c , d ) ) n=2,a 为原子,(b, c, d)为子表
6. GetHead{ ( ( ) ) }= ( ) .
7. GetTail{ ( ( ) ) }= ( ) .
(a, b)
§5.4 广义表的类型定义 ❖注意:( )和( ( ) )的区别
前者为空表,长度=0,深度=1; 后者长度=1,深度=2,表头、表尾均为( )
§5.5 广义表的存储结构
❖广义表的存储结构
§5.4 广义表的类型定义
❖广义表的特点
▪ 有深度
广义表的深度定义为广义表中括弧的最大重数
如: H = (d, (e,( )))深度为3 注意:(1)空表的深度为1;

零基础学数据结构 第8章 广义表

零基础学数据结构 第8章 广义表

(5)CopyGList(&T,L):复制广义表。由广义表L复制得到广义表T。复
制成功返回1;否则,返回0。
8.2 广义表的头尾链表表示与实现
8.2.1 广义表的头尾链表存储结构
因广义表中有两种元素:原子和子表,所以广义表的链表结点也分 为两种:原子结点和子表结点,其中,子表结点包含3个域:标志域、 指向表头的指针域和指向表尾的指针域。原子结点包含两个域:标志 域和值域。表结点和原子结点的存储结构如图8.1所示。
8.2 广义表的头尾链表表示与实现
(3)求广义表的长度。求广义表的长度只需要沿着表尾指针tp查找下去,统计子 表个数,直到tp为NULL为止。如果广义表是空表,则广义表的长度为0。否则, 将指针p指向结点的表尾指针,统计广义表的长度。 int GListLength(GList L) { int length=0; while(L) /*如果广义表非空,则将p指向表尾指针,统计表的长度*/ { L=L->ptr.tp;E就是一个递 Nhomakorabea的广义表。
任何一个非空广义表的表头可以是一个原子,也可以是一个广义表,而 表尾一定是一个广义表。例如: head(A)=(),tail(A)=(),head(C)=a,tail(C)=((b,c)), head(D)=A,tail(D)=(B,C) 其中,head(A)表示取广义表A的表头元素,tail(A)表示取广义表A的表 尾元素。
8.2 广义表的头尾链表表示与实现
求广义表的深度的算法实现如下。 int GListDepth(GList L) { int max,depth; GLNode *p; if(!L) /*如果广义表为空,则返回1*/ return 1; if(L->tag==ATOM) /*如果广义表是原子,则返回0*/ return 0; for(max=0,p=L;p;p=p->ptr.tp) /*逐层处理广义表*/ { depth=GListDepth(p->ptr.hp); if(max<depth) max=depth; } return max+1; }

数据结构数组和广义表

数据结构数组和广义表

数据结构05数组与广义表数组与广义表可以看做是线性表地扩展,即数组与广义表地数据元素本身也是一种数据结构。

5.1 数组地基本概念5.2 数组地存储结构5.3 矩阵地压缩存储5.4 广义表地基本概念数组是由相同类型地一组数据元素组成地一个有限序列。

其数据元素通常也称为数组元素。

数组地每个数据元素都有一个序号,称为下标。

可以通过数组下标访问数据元素。

数据元素受n(n≥1)个线性关系地约束,每个数据元素在n个线性关系地序号 i1,i2,…,in称为该数据元素地下标,并称该数组为n维数组。

如下图是一个m行,n列地二维数组A矩阵任何一个元素都有两个下标,一个为行号,另一个为列号。

如aij表示第i行j列地数据元素。

数组也是一种线性数据结构,它可以看成是线性表地一种扩充。

一维数组可以看作是一个线性表,二维数组可以看作数据元素是一维数组(或线性表)地线性表,其一行或一列就是一个一维数组地数据元素。

如上例地二维数组既可表示成一个行向量地线性表: A1=(a11,a12,···,a1n)A2=(a21,a22, ···,a2n)A=(A1,A2, ···,Am) ············Am=(am1,am2, ···,amn)也可表示成一个列向量地线性表:B1=(a11,a21,···,am1)B2=(a12,a22, ···,am2)A=(B1,B2, ···,Bm) ············Bn=(a1n,a2n, ···,amn)数组地每个数据元素都与一组唯一地下标值对应。

数据结构第五章 数组和广义表

数据结构第五章 数组和广义表

5.3.1
特殊矩阵
1、对称矩阵 在一个n阶方阵A中,若元素满足下述性质: aij = aji 1≤i,j≤n 则称A为对称矩阵。 a11 1 5 1 3 7 a21 a 22 5 0 8 0 0 a31 a32 a33 1 8 9 2 6 ……………….. 3 0 2 5 1 an 1 a n 2 a n 3 …a n n 7 0 6 1 3
第5章
数组和广义表
5.1 数组的定义
5.2 数组的顺序表示和实现
5.3 矩阵的压缩存储
5.3.1 特殊矩阵
5.3.2 稀疏矩阵
5.4 广义表的定义
5.1 数组的定义
数组-----线性表的扩展 A =(a0,a1,a2,…,an-1)
a00 a10 ┇ Am×n= ai0 ┇ am-1,0 a01 … a0j … a11 … a1j … ┇ ai2 … aij … ┇ am-1,2 … am-1,j … a0,n-1 a1,n-1 ai,n-1 am-1,n-1 α0 α1 ┇ Am×n= α i ┇ α m-1
Assign( &A, e, index1, ..., indexn) 赋值操作 初始条件:A是n维数组,e为元素变量,随后是n个下标值。 操作结果:若下标不超界,则将e的值赋给所指定的A的元 素,并返回OK。 对于数组来说一旦维数确定了,每个元素的下标确定了, 那么整个数组就确定了,这样的一个数组结构除了能改变 某元素的值,其他的不能再改变。
5.2 数组的顺序表示和实现
数组类型特点: 1) 只有引用型操作,没有加工型操作; 2) 数组是多维的结构,而存储空间是一个一维的结构。 有两种顺序映象的方式。
有两种顺序映像方法: 1)以行序为主序(行优先,先行后列):先存储行号较小 的元素,行号相同者先存储列号较小的元素;

数据结构 第三章(广义表)

数据结构 第三章(广义表)
e建立其链表结构一般地对于输入s1的结点组成的表这个表由s的第一个左括号引出建立其链表结构对的结点递归建立与?xn1对应的表尾并链接到存放x的结点之后如果xm1形式可以递归建立与之对应的子表是原子直接存入相应结点即可左括号是重要的导航标记
线性表L
= <a1, …, ai,…,an>
使用单链表存储 结点包含有数据域data和指针域next 指针p指向值为ai的节点。
先建立存放x0的结点
递归建立与‚x1, …, xn-1)”对应的表尾,并链接 到存放x0的结点之后
如果x0是子表 则x0一定以左括号开头 x0的其它部分一定为‚y0, …, ym-1)”形式 可以递归建立与之对应的子表
若x0不以左括号‚(”开头 则x0是原子
直接存入相应结点即可
左括号是重要的导航标记。在顶层,第一个符号一定 是左括号。
写为A = (a0, a1, …, an-1)
A是名字,n是表的长度。按惯例,表名 用大写字母表示,原子用小写字母表示。如果 n≥1,则a0是A的表头,(a1, …, an-1)是A的表尾
广义表的例子:
(1)D = ( ):长度为0的空表。 (2)A = (a, (b, c)):长度为2的表,其第一个元素是 原子a,第二个元素是表 (b, c)。 (3)B = (A, A, ( )):长度为3的表,其前两个元素是 表A,第三个元素是空表。 (4)C = (a, C):长度为2的递归表,C = (a, (a, (a, …),具有无限层次。
A
B
C
E
A
A b c B a
b
c
a
.
b
c
a
(d) E=(a,E)
(a)A=(b,c)

数据结构 第五章 数组和广义表

数据结构 第五章 数组和广义表

则行优先存储时的地址公式为: LOC(aij)=LOC(ac1,c2)+[(i-c1)*(d2-c2+1)+j-c2)]*L
数组基址
aij之前的行

总列数,即 第2维长度
aij本行前面
的元素个数
单个元素 长度
例2一个二维数组A,行下标的范围是1到6,列下标的范围是0
到7,每个数组元素用相邻的6个字节存储,存储器按字节编址。 288 个字节。 那么,这个数组的体积是
2.若对n阶对称矩阵A以行序为主序方式将其下三 角形的元素(包括主对角线上所有元素)依次存 放于一维数组B[1..(n(n+1))/2]中,则在B 中确定aij(i<j)的位置k的关系为( )。 A. i*(i-1)/2+j B. j*(j-1)/2+i C. i*(i+1)/2+j D. j*(j+1)/2+i
维界虽未变,但此时的a[32,58]不 再是原来的a[32,58]
例5:假设有三维数组A7×9×8,每个元素用相邻的6个字节存
储,存储器按字节编址。已知A的起始存储位置(基地址)为 1000,末尾元素A[6][8][7]的第一个字节地址为多少?若按 高地址优先存储时,元素A[4][7][6]的第一个字节地址为多 少? 答: 末尾元素A[6][8][7]的第1个字节地址= 1000 +(9*8*6+8*8+7)*6=4018 提示:将第1维看作“页码”,后面两维就是每页上的二维数组 。 计算地址 的意义: 只要计算出任一数组元素的地址,就 能对其轻松地进行读写操作!
4.已知数组A[0..9,0..9]的每个元素占5个存储 单元,将其按行优先次序存储在起始地址为 1000的连续的内存单元中,则元素A[6,8]的 地址为_________
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基本操作:
InitArray(&A, n, bound1, ..., boundn)
DestroyArray(&A) Value(A, &e, index1, ..., indexn) Assign(&A, e, index1, ..., indexn)
InitArray(&A, n, bound1, ..., boundn) 操作结果:若维数 n 和各维长度合法, 则构造相应的数组A,并 返回OK。
(数组)提要
5.1.1 数组的类型定义 5.1.2 数组的顺序表示和实现
5.1.3 矩阵的压缩存储
ADT Array { 数据对象: D={aj1,j2, ..., jn| ji =0,...,bi -1, i=1,2,..,n (n>0), aj1,j2, ..., jn ∈ElemSet}
数据关系:
} }// transposeSMatrix 算法的时间复杂度:O(nu×tu)
用常规的二维数组表示时的算法:
for (col=1; col<=nu; ++col) for (row=1; row<=mu; ++row) T[col][row] = M[row][col];
其时间复杂度为: O(mu×nu)
0
0
0
0
0
0
以常规方法,即以二维数组表示高阶 的稀疏矩阵时会产生的问题:
1) 零值元素占了很大空间; 2) 计算中进行了很多和零值的运算, 遇除法,还需判别除数是否为零。
解决问题的原则:
1) 尽可能少存或不 即:
尽可能快地找到与下标值(i,j)对应的元素, 尽可能快地找到同一行或同一列的非零元素。
的存储位置是其下标的线性函数。
以“列序为主序”的存储映象
例如: 二维数组Am×n
a0,0 a1,0 … am-1,0 … … a0,n-1 a1, n-1 … am-1,n-1
L
按列号从小到大的顺序,先将第一列中元素全部存 放完,再存放第二列元素,第三列元素,依次类推……
二维数组A中任一元素ai,j 的存储位置 LOC(i,j) = LOC(0,0) + (m×j+i)×L
0 0 36 14 7 0 0 0 0 0 0 28 5 0 0
在三元组表表示的稀疏矩阵中,怎样 求得它的转置呢?
从转置的性质知道,将A转置为B,就是将A的三元组 表a.data变为B的三元组表b.data,这时可以将a.data中 i和j的值互换,则得到的b.data是一个按列序为主序排 列的三元组表,再将它的顺序适当调整,变成行序为主 序排列,即得到转置矩阵B。下面将用两种方法处理:
数组和广义表可以看成是线性表 在以下含义上的扩展: ——表中的数据元素本身也是一个数 据结构。
5.1 数组
数组是大家都已经很熟悉的一种数据类型, 几乎所有高级程序设计语言中都设定了数组类 型。在此,我们仅简单地讨论数组的逻辑结构 及在计算机内的存储方式。
一. 多维数组的概念
1.一维数组
一维数组可以看成是一个线性表或一个向量,它 在计算机内存放在一块连续的存储单元中,适合于随 机查找。这在第2章的线性表的顺序存储结构中已经讨 论。
例如:
M=
0 12 9 0 -3 0 0 0 0 0
0 0 0 0
0 0
0 0
0 0 0 0
0 14 0 0
0 24
0 18
15 0
0
0
0
-7
0
0
0
0
0
0 i j 2 3 1 6 3 2 1 4 e 12 9 -3 14 24 18 15 -7
矩阵M可表示为:
(TSMatrix M)
M.data: M.mu=6 M.nu=7 M.tu=8
2. 稀疏矩阵
何谓稀疏矩阵?
假设 m 行 n 列的矩阵含 t 个非零元素,则称
mt n
为稀疏因子。 通常认为 0.05 的矩阵为稀疏矩阵。
非零元在矩阵中随机出现。
例如:
M=
0 12 9
0
0
0
0
0
-3 0
0
0
0
0
0
0 0
0
0
0
0 0
0 14 0 0
0 24
0 18
15 0
0
0
0
-7
推广到一般情况,可得到 n 维数 组数据元素存储位置的映象关系:
LOC(j1, j2, ..., jn ) = LOC(0,0,...,0) + ∑ c j i i i =1
其中 cn = L,ci-1 = bi ×ci , 1 < i n。
见教材P.93
n
称为 n 维数组的映象函数。数组元素
a21 a22 … a2n
……
an1 an2 … ann
以对称矩阵为例,n阶对称矩阵A满足: aij=aji 1≤i,j≤n 可为每一对对称元分配一个存储空间。若 以行序为主序存储其下三角中的元,以一维数 组s[n(n+1)/2]作为其存储结构,则s[k]和矩阵元 aij之间的对应关系为:
i(i-1)/2+j-1 k= j(j-1)/2+i-1 (i< j) (i≥ j)
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。
相比较后可以发现,当非零元的个数tu与mu×nu 同数量级时, transposeSMatrix算法的时间复杂度就 成为O(mu×nu2)了,比不压缩存储时的时间复杂度要 大。因此,该算法仅适于tu<<mu×nu的情况。
(2)按照A的行序进行转置(快速转置)
即按a.data中三元组的次序进行转置,并将转置 后的三元组放入b中恰当的位置。首先,在转置前求出 矩阵A的每一列col(即B中每一行)的第一个非零元转 置后在b.data中的正确位置cpot[col](1≤col≤a.nu), 然后,在对a.data的三元组依次作转置时,只要将三 元组按列号col放置到b.data[cpot[col]]中,之后将 cpot[col]内容加1,以指示第col列的下一个非零元的 正确位置。
2.二维数组
二维数组可以看成是向量的推广。例如,设A是 一个有m行n列的二维数组,则A可以表示为:
a00 a10
A= …… a0n-1 …… a1n-1 ………………………….
……
a01 a11
am-1 0 am-1 1
am-1 n-1
在此,可以将二维数组A看成是由 m个行向量 [X0, X1, …,Xm-1]T组成,其中,Xi=( ai0, ai1, ….,ain-1), 0≤i≤m-1;也可以将二维数组A看成是由n个列向量[Y0, Y1, ……,Yn-1]组成,其中 Yj=(a0j, a1j, …..,am-1j), 0≤j≤n-1。由此可知二维数组中的每一个元素最多可 有两个直接前驱和两个直接后继(边界除外)。
二维数组的定义:
数据对象:
D = {aij | 0≤i≤b1-1, 0 ≤j≤b2-1, aij∈ElemSet} 数据关系:
R = { ROW, COL }
ROW = {<ai,j,ai+1,j>| 0≤i≤b1-2, 0≤j≤b2-1} COL = {<ai,j,ai,j+1>| 0≤i≤b1-1, 0≤ j≤b2-2}
以“行序为主序”的存储映象
例如: 二维数组Am×n
a0,0 a0,1 … a0,n-1 … … am-1,0 am-1,1 … am-1,n-1
L
按行号从小到大的顺序,先将第一行中元素全部存 放完,再存放第二行元素,第三行元素,依次类推……
二维数组A中任一元素ai,j 的存储位置 LOC(i,j) = LOC(0,0) + (n×i+j)×L
为了求得位置向量cpot,要先求出A的每一列中非 零元个数num[col],然后利用下面公式:
{q=1;
for ( col=1; col<=M.nu; ++col)
//按列号扫描
for( p=1; p<=M.tu; ++p) //对三元组扫描 if (M.data[p].j= =col) //进行转置 { T.data[q].j=M.data[p].i; T.data[q].i=M.data[p].j; T.data[q].e=M.data[p].e; ++q; }
5.1.1 数组的类型定义
R={R1, R2, ..., Rn} Ri={<aj1,... ji,... jn , aj1, ...ji +1, ...jn > | 0 jk bk -1, 1 k n 且k i, 0 ji bi -2, i=2,...,n }
基本操作:
} ADT Array
1 1 3 3 4 5 6 6
三元组顺序表表示的稀疏矩阵的转置运算。
转置是矩阵中最简单的一种运算。对于一个mn的 矩阵A,它的转置矩阵B是一个nm的矩阵,且 B[i][j]=A[j][i],1≤i≤n,1≤j≤m。
相关文档
最新文档