广义表
广义表不仅跟线性表一样可以表示简单是线性顺序关系,而且可以表达更复杂的非线性多元关系。
G L i s t = ( a 1 , a 2 , . . . , a i − 1 , a i , a i + 1 , . . . , a n ) GList = (a_1, a_2,...,a_{i-1},a_i,a_{i+1},...,a_n) GList=(a1,a2,...,ai−1,ai,ai+1,...,an)
其中, a i a_i ai可以是单元素,也可以是广义表。
由于广义表的元素可以是不同的结构,因此不适于顺序存储,通常用链式存储结构,也就是用由结点组成的链表来表示广义表。结点对应每个元素。如果该元素还是一个广义表,则通过该节点引出另一个链表。
广义表的结点可能由两种情况。
- 单元素:需要一个域来存储该单元素的值
- 广义表:需要一个域来指向另一个链表。
数据结构
typedef int ElementType;
typedef struct GNode* GList;
typedef struct GNode* PtrToGNode;
struct GNode {int Tag; // 标志域: 0表示该节点为单元素; 1表示该节点为广义表union MyUnion{//子表指针域Sublist和单元素数据域Data复用,即共享存储空间ElementType Data;GList Sublist;};PtrToGNode Next;//指向后继结点};
举例: 广义表LS:(a, (b,…),(c,d),(e,f))
多重链表
存在结点属于多个链的链表叫做多重链表。
一般来说,多重链表的每个结点的指针域会有很多个,如前面列子包含Next和Sublist的两个指针域。但是包含两个指针域的链表不一定是多重链表,如双向链表,其每个结点还是属于同一个链表。
稀疏矩阵的存储
对于矩阵A
A = [ 18 0 0 2 0 0 27 0 0 0 0 0 0 − 4 0 23 − 1 0 0 12 ] A = \begin{bmatrix} 18& 0 &0 &2 &0 \\ 0& 27 &0 &0 &0 \\ 0& 0 & 0 & -4 & 0 \\ 23& -1 & 0 &0 &12 \end{bmatrix} A= 1800230270−1000020−4000012
可以采用一种经典的多重链表——十字链表来存储稀疏矩阵。
特点
(1)、只存储矩阵中非0的元素项;
(2)、结点的数据域:行坐标Row、列坐标Col、数值Value
(3)、每个结点通过两个指针域,把同行、同列串起来
行指针(或者称为向右指针)Right
列指针(或者称为向下指针):Down
(4)、用一个Tag来区分头结点和非0元素结点
(5)、头节点的标识值为“Head”,矩阵非0元素结点的标识值为“Term”
结点分类:
- 每行每列的头结点 (右图)
- 矩阵的非0元素节点 (左图)
A矩阵的十字链表表示