250 likes | 429 Views
æ•°æ®ç»“æž„. ä¸å¤®å¹¿æ’电视大å¦å¼€æ”¾æ•™è‚²è¯•点课程. 辅导教师 倪政林. æ•°æ®ç»“æž„. ç¬¬ä¸€ç« ç»ªè®º ç¬¬äºŒç« çº¿æ€§è¡¨ ç¬¬ä¸‰ç« ç¨€ç–矩阵和广义表 ç¬¬å››ç« æ ˆå’Œé˜Ÿåˆ— ç¬¬äº”ç« æ ‘å’ŒäºŒå‰æ ‘ 第å…ç« äºŒå‰æ ‘的应用 ç¬¬ä¸ƒç« å›¾ ç¬¬å…«ç« æŸ¥æ‰¾ 第ä¹ç« 排åº. ç¬¬ä¸‰ç« ç¨€ç–矩阵和广义表. 稀ç–矩阵的概念. (Sparse Matrix) 是矩阵ä¸çš„一ç§ç‰¹æ®Šæƒ…况, 它的éžé›¶å…ƒç´ 的个数远远å°äºŽé›¶å…ƒç´ 的个数. 1 2 3 4 5 6 1 3 0 0 5 0 0 2 0 0 - 2 0 0 0
E N D
数据结构 中央广播电视大学开放教育试点课程 辅导教师 倪政林
数据结构 第一章 绪论 第二章 线性表 第三章 稀疏矩阵和广义表 第四章 栈和队列 第五章 树和二叉树 第六章 二叉树的应用 第七章 图 第八章 查找 第九章 排序
第三章 稀疏矩阵和广义表
稀疏矩阵的概念 (Sparse Matrix)是矩阵中的一种特殊情况, 它的非零元素的个数远远小于零元素的个数 1 2 3 4 5 6 1 3 0 0 5 0 0 2 0 0 -2 0 0 0 3 1 0 4 0 6 0 4 0 0 0 0 0 0 5 0 0 -1 0 0 0 元素的占用率: 7/30
压缩存储方法: 一、三元组顺序表 二、带行指针向量的链接存储 三、十字链表
1 2 3 4 5 6 1 3 0 0 5 0 0 2 0 0 -2 0 0 0 3 1 0 4 0 6 0 4 0 0 0 0 0 0 5 0 0 -1 0 0 0 稀疏矩阵的压缩顺序存储 {(1,1,3),(1,4,5),(2,3,-2), (3,1,1),(3,3,4),(3,5,6), (5,3,-1)} Struct Tripe{ Int row,col; Elemtype val;}; Struct Smatrix{ Int m,n,t; Triple sm[MaxTerms+1]}
稀疏矩阵的元素输入算法 Void inputmatrix(smatrix& M,int m,int n) { M.m=m;M.n=n; int row,col,val; Int k=0; Cin>>row>>col>>val>>cend; While (row!=0){ K++; M.sm[k].row=row; M.sm[k].row=col; M.sm[k].row=val; cin>>row>>col>>val;} M.t=k; }
用“三元组”表示实现矩阵转置 原矩阵 转置后矩阵
Smatrix Transpose(smatrix& M) {int m,n,t; smatrix s; m=M.m; n=M.n; t=M.t; s.m=n; s.n=m; s.t=t; if(t==0) return s; int k=1; for(int col=1;col<=n;col++) for(int i=1;i<=t;i++) if(M.sm[i].col==col) {s.sm[k].row=col; s.sm[k].col=M.sm[i].row; s.sm[k].val=M.sm[i].val; K++;} return s;} 转置算法的设计
Smatrix Transpose(smatrix& M) {………….. int k=1; for(int col=1;col<=n;col++) for(int i=1;i<=t;i++) if(M.sm[i].col==col) {s.sm[k].row=col; s.sm[k].col=M.sm[i].row; s.sm[k].val=M.sm[i].val; K++;} return s;} M row col val 1 2 3 4 5
二、带行指针向量的链接存储 需要把具有相同行号的三元组结点按照列号从小到大的顺序链接成一个单链表,每个三元组结点的类型可定义为: row col val next
带行指针向量的链接存储抽象数据类型 Struct triplenode{ Int row,col; Elemtype val; Triplenode* next; }; Struct Lmatrix { Int m,n ,t; Triplenode* vector[maxrows+1] }
1214 15-5 22-7 3 136 3 4 28 vector /\ /\ 2 2 -7 3 1 36 3 4 28 1 5 -5 1 2 14 /\ /\ /\ 三元组 行指针向量
3 0 0 5 0 -1 0 0 2 0 0 0 三、 十字链表 cv ^ rv 1 1 3 1 4 5 ^ ^ 2 2 -1 ^ ^ 3 1 2 ^ ^
广义表的概念 是线性表的推广,表中元素可以是表. A=()/空表 B=(e) C=(a,(b,c,d)) D=(A,B ,C)=((),(e),(a,(b,c,d)) )/表长为:3 E=( (a,(a,b),((a,b),c)) )/表长为: 1
广义表是递归定义的线性结构 1)N=0时,表是一空表; 2)N=1时,表中有一个元素, 该元素可能是一个表; 3)当N>1时,表中的元素是由上述1)或2)组成. 4)是上述1)至3)的过程构造的表称广义表.
广义表是多层次的线性结构 D= ((),(e),(a,(b,c,d)) ) E=( (a,(a,b),((a,b),c) ) ) D E A B C e a a b a c b d c a b
广义表结构的特点: • 数据元素有相对次序; • 2)长度为最外层包含元素个数; • 3)深度为所含括弧的重数; • 原子:深度为 0;空表:深度为 1; • 4)可以共享; • 5)可以是一个递归的表。
tag=1 sublist next tag=0 data next 广义表的存储结构 采用头、尾指针的链表结构 表结点: 原子结点:
广义表的运算 1.求广义表长度 2.求广义表的深度 递归函数 含直接或间接调用本函数语句的函数
1.求广义表长度的递归算法 intLenth(GLNode* GL) { if (GL!=NULL) return 1+Lenth(GL -> next) else return 0; } D Len=lenth(D)
非递归算法如下: int Lenth(GLNode* GL) { int len=0; while(GL!=NULL) { len++; GL=GL->next; } return len; } D Len=lenth(D)
2.求广义表的深度 将广义表分解成 n 个子表,分别 (递归)求得每个子表的深度, 深度=Max {子表的深度} +1 可以直接求解的两种简单情况为: 空表的深度 = 1 原子的深度 = 0
L L L … GL 1 1 1 L->sublist L->sublist L->sublist Max=0 while(GL!=NULL) { if(GL->tag==true) { int dep=Depth(L->sublist); if(dep>max) max=dep; } GL=GL->next; }
Int Depth(GLnode* GL) {int Max=0 while(GL!=NULL) { if(GL->tag==true) { int dep=Depth(L->sublist); if(dep>max) max=dep;} GL=GL->next; } return max+1; } Int dep=Depth(L);