数据结构之广义线性表
Posted dreamworldclark
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之广义线性表相关的知识,希望对你有一定的参考价值。
- 数组(定义、顺序存储结构)
- 矩阵的压缩存储
- 广义表
- 数组的顺序存储(将二维的数组压缩要一维存储)
- 行优先,低下标(aij的位序为k<以1作为开始>,每行n个元素):
- k = (i - 1) * n + (j - 1) + 1 = (i - 1) * n + j
- LOC(i,j) = LOC(1,1) + (k -1 ) *L
- 列优先,高下标
- k = (j -1) * m + i
- LOC(i, j) = LOC(1,1) + (k - 1) * L
- 行优先,低下标(aij的位序为k<以1作为开始>,每行n个元素):
- 矩阵的压缩存储(对称阵)
- 方式:取下三角形按照行的顺序放入数组
- 下标公式(取大的下标):
- k = i * (i + 1) / 2 + j , when i >= j
- k = j * (j + 1) / 2 + i , when j > i
- 矩阵的压缩存储(三角阵:有一个三角区域都是一个常量c)
- 方式:将三角部分的元素根据对称阵的方式存储,然后在最后添加c(k = n(n+1)/2)<n是右下角元素的坐标即正方形的宽度+1(0开始计算)> 下标公式(以上三角形常量为例子):
- k = i(i+1)/2+j , when i >= j
- k = n*(n+1)/2 *必须是0开始
- 矩阵压缩(对角阵:各对角线有大量相同的元素)
- 方式:略
- 下标公式
- k = 2i + j
- LOC(i, j) = Locate(0,0) + (2i+j)*L
- 稀疏矩阵的压缩
- 存储方式:
- 三元组顺序存储
template <class T> struct MTNode{ int i, j; T e; }; template <class T> typedef struct L { MTNode<T> *data; int mu, nu, tu; }TSMatrix;
- 行逻辑链接的顺序表(简化版非链表结构)
template <class T> struct MTNode{ int i, j; T e; }; typedef struct L { MTNode *data; int *rpos /*the index of evey firstnotnull in the row TSMtrix.*/ int mu,nu,tu; }SMatrix;
- 带行指针向量的链式存储(上面的链表版本)
typedef struct L { MTNode *data; int *rpos /*the index of evey firstnonull in the row TSMtrix.*/ int mu,nu,tu; }SMatrix;
- 十字链表(拓展2、3,不仅仅是停留在行的层面,我把它理解为稀疏矩阵提取元素二维数组链表化)
struct MTNode{ int i, int j; T e; MTNode * dowm; MTNode * right; //used to bulid linked list } typedef struct L { int mu,nu,tu; MTNode *rpos; MTNode *cpos; }LMatrix;
- 三元组顺序存储
- 存储方式:
- 稀疏矩阵的运算
- 矩阵转置:
- 直接取顺序存(傻瓜式,从A中按照列的升序直接取元素按照顺序存入B中)
void MatrixTrans_I(TSMatrix A, TSMatrix &B){ B.mu = A.nu; B.nu = A.mu; B.tu = A.tu; //A convert the arguments to B; if(B.tu) //confirm it has element { q = 0; //q is the index of the TSMatrix B for(col = 0; col < A.nu; col++) for(p = 0; p < A.mu; p++) //p is the index of the TSMatrix A //search every row. if(A.data[p].j == col) { B.data[q].i = A.data[p].j; B.data[q].j = A.data[p].i; B.data[q].e = A.data[p].e; ++q; } } }
- 顺序取直接存(快速转置,提前需要知道每一个列号的Index数组cpot[col]和它有几个元素num[col],从A中顺序取元素,直接存到B)
void MatrixTrans_II(TSMatrix A, TSMatrix &B){ B.mu = A.nu; B.nu = A.mu; B.tu = A.tu; int i, k, p,q; int * num, * cpot; num = new int[B.nu]; cpot = new int[B.nu]; if(B.tu){ for(i = 0; i < B.nu; i++){ num[i] = 0; //initialization } for(k = 0; k < B.nu; k++){ num[A.data[k].j]++; //counter } copt[0] = 0; for(k = 1; k < B.nu; k++){ cpot[k] =copt[k - 1] + num[k - 1]; } for(p = 0; p < A.nu; p++){ //get the elemnt int A in sequence //and then insert it into the right //postion. q = copt[A.data[p].j]; B.data[q].i = A.data[p].j; B.data[q].j = A.data[p].i; B.data[q].e = A.data[p].e; copt[A.data[p].j]++; } } }
- 直接取顺序存(傻瓜式,从A中按照列的升序直接取元素按照顺序存入B中)
- 矩阵加法(有时间补充)
- 矩阵乘法(有时间补充)
- 矩阵转置:
- 广义表
- 逻辑结构:广义表(generalized Lists)又称列表(lists),是n(n>=0)个数据元素a1,a2,a3,...,ai,...,an的有限序列,一般记作:LS = (a1,a2,...,ai,...,an).ai是广义表LS的成员,它可以是单个元素,也可以是一个广义表,分别称为LS的单元素(也可以成为原子)和子表。用大写字母表示广义表,数据元素是原子时用小写字母,数据元素是子表时,用‘()"括起来。其中,深度表示嵌套层数,长度是元素个数。注意!如果E = (a, E)这样嵌套的话,长度是2,但是深度是无穷大! 一棵树可以用一个广义表来表示。
- 广义表的存储(由于数据元素具有不同的结构,因此难以用顺序结构表示,所以使用链式存储结构):
- 头尾表示法(层级设计,层层扫描,一个括号归于一层,原子必归于表节点,一次一个输出):
enum Elemtag{Atom,List}; //0 is atom node, 1 is list node; template <class T> struct GLNode { Elemtag tag; union { T data; struct { GLNode * hp, *tp; }ptr; }; };
- 孩子兄弟表示法(一个节点一定有兄弟(可以是Null,tp),一个节点可能有儿子(hp),若是儿子没有孩子,我们就像看看他长什么样子,有没有兄弟,并且为什么不可以用tag告诉我到底是什么呢?)
enum Elemtag{Atom, List}; template <class T> struct GLNode { Elemtag tag; union{ T data; struct GLnode* hp; //hp point to the son } struct GLNode *tp; //tp point to the brother }ptr;
- 计算头尾表示法的广义表的深度
int depth(GLNode * ls){ int h,t; if(ls == NULL)//if the node is not exist return 1 return 1; else if(ls -> tag == 0) return 0;//if the node is atom return 0 else { h = depth(ls -> hp); t = depth(ls -> tp); if(t > h) return t; else return h+1; //recursion } }
- 计算头尾表示法的广义表的长度
int Length(GLNode *ls){ if(ls == NULL) return 0; int max = 1; //search in y GLNode* p = ls -> tp; while(p){ max++; p = p -> tp; } return max; }
- 创建广义表(首尾表示法,使用递归的方法)
template <class T> GLNode<T>* Crtlists(string st){ if(st == "()") ls = NULL; else if(st.Length() == 1){ ls = new GLNode<T>; ls -> tag = 0; ls -> data = st[0]; } else { ls = new GLNode<T>; ls -> data = 1; p = ls; st = st.substring(1, st.length()-2); //remove the "()" do{ Server(sub,hsub); p -> ptr.hp = Crtlists(hsub); q = p; //This is a sub remove "()"outside //and the element in it. if(sub!="") { p = new GLNode<T>; p -> tag = 1; q -> ptr.tp = p; }; } while(sub != ""); q -> ptr.tp = NULL;//seal the last one. } return(ls); }
- 头尾表示法(层级设计,层层扫描,一个括号归于一层,原子必归于表节点,一次一个输出):
这个章节的内容理解并不是很难,要是想要实现各种递归还真的是头疼。。。
以上是关于数据结构之广义线性表的主要内容,如果未能解决你的问题,请参考以下文章