【Data structure】Storage structure and basic operation of generalized table (C language)

1. Basic concept of generalized table

A generalized table is a finite sequence of n data elements (d1, d2, d3,...,dn), and di can be either a single element or a generalized table. Usually recorded as GL = (d1, d2, d3, ..., dn), n is the generalized table length. If di is a generalized table, then di is said to be a sub-table of the generalized table GL. In the generalized table GL, d1 is the header of the generalized table, and the table composed of other parts is called the footer of the generalized table.
For example:
D = (): empty list, length is 0.
A = (a, (b, c)): a generalized table with a table length of 2, the first element is a single data a, and the second element is a subtable (b, c).
B = (A, A, D): a generalized list of length 3, the first two elements are list A, and the third element is an empty list D.
C = (a, C): a generalized table of length 2 recursively defined, C is equivalent to an infinite table C = (a, (a, (a, (…)))).

① The elements of the generalized table can be sub-tables, and the sub-tables can also be sub-tables, so the generalized table is a multi-layer structure.
② A generalized table can be shared by other generalized tables. For example, table B shares table A in a generalized sense, and it is not necessary to list the contents of table A in table B, as long as the name of the subtable can be used to refer to the table.
③ Generalized tables are recursive, such as generalized table C.

2. Storage structure of generalized table

2.1 Head-tail linked list storage structure

Each element in a generalized table is represented by a node, and there are two types of nodes in the table: one is a single element node, that is, an atomic node; the other is a sub-list node, that is, a table node. Any non-empty generalized table can be decomposed into two parts: header and footer. Conversely, a certain pair of header and footer can uniquely determine a generalized table. Therefore, a table node can be composed of three fields: a flag field, a pointer field to the head of the table, and a pointer field to the end of the table, while an element node only needs two fields: the flag field and the value field.
node structureHead-tail linked list storage structure
the code

/*广义表的头尾链表存储结构*/
typedef enum {
    
     ATOM, LIST }ElemTag;		//ATOM=0,表示原子;LIST=1,表示子表
typedef struct GLNode {
    
    
	ElemTag tag;						//标志位tag用来区分原子结点和表结点
	union {
    
    
		int atom;						//原子结点的值域
		struct {
    
    
			struct GLNode* hp, * tp		//表结点的指针域htp,包括表头指针域hp和表尾指针域tp
		}htp;
	}atom_htp;							//atom_htp是原子结点的值域atom和表结点的指针域htp的联合体域
}GLNode, * GList;

2.2 Same layer node chain storage structure

Both atomic nodes and table nodes are composed of three fields.
node structureSame layer node chain storage structure
the code

/*广义表的同层结点链存储结构*/
typedef enum {
    
     ATOM, LIST }ElemTag;		//ATOM=0,表示原子;LIST=1,表示子表
typedef struct GLNode {
    
    
	ElemTag tag;						//标志位tag用来区分原子结点和表结点
	union {
    
    
		int atom;						//原子结点的值域
		struct GLNode* hp;				//表头指针域
	}atom_hp;							//atom_hp是原子结点的值域atom和表结点的表头指针域hp的联合体域
	struct GLNode* tp;					//同层下一个结点的指针域
}GLNode, * GList;

3. Basic operations of generalized tables

3.1 Find the header and tail of the table

/*求广义表L的表头,并返回表头指针*/
GList Head(GList L) {
    
    
	if (L == NULL)					//空表无表头
		return NULL;
	if (L->tag == ATOM)				//原子不是表
		exit(0);
	else
		return L->atom_htp.htp.hp;	//返回表头指针
}

/*求广义表L的表尾,并返回表尾指针*/
GList Tail(GList L) {
    
    
	if (L == NULL)					//空表无表尾
		return NULL;
	if (L->tag == ATOM)				//原子不是表
		exit(0);
	else
		return L->atom_htp.htp.tp;	//返回表尾指针
}

3.2 Calculate the length and depth

/*求广义表长度*/
int Length(GList L) {
    
    
	int k = 0;
	GLNode* s;
	if (L == NULL)
		return 0;					//空表长度为0
	if (L->tag == ATOM)				//原子不是表
		exit(0);
	s = L;
	while (s != NULL) {
    
    				//统计最上层表的长度
		k++;
		s = s->atom_htp.htp.tp;
	}
	return k;
}

/*求广义表的深度*/
int Depth(GList L) {
    
    
	int d, max;
	GLNode* s;
	if (L == NULL)
		return 1;					//空表深度为1
	if (L->tag == ATOM)
		return 0;					//原子深度为0
	s = L;
	while (s != NULL) {
    
    				//求每个子表的深度的最大值
		d = Depth(s->atom_htp.htp.hp);
		if (d > max)
			max = d;
		s = s->atom_htp.htp.tp;
	}
	return (max + 1);				//表的深度等于最深子表的深度+1
}

3.3 Statistical number of atoms

/*统计广义表中原子结点数目*/
int CountAtom(GList L) {
    
    
	int n1, n2;
	if (L == NULL)
		return 0;							//空表中没有原子
	if (L->tag == ATOM)
		return 1;							//L指向单个原子
	n1 = CountAtom(L->atom_htp.htp.hp);		//统计表头中的原子数目
	n2 = CountAtom(L->atom_htp.htp.tp);		//统计表尾中的原子数目
	return (n1 + n2);
}

3.4 Replication of generalized tables

/*复制广义表*/
int CopyGList(GList S, GList* T) {
    
    
	if (S == NULL) {
    
    				//复制空表
		*T = NULL;
		return OK;
	}
	*T = (GLNode*)malloc(sizeof(GLNode));
	if (*T == NULL)
		return ERROR;
	(*T)->tag = S->tag;
	if (S->tag == ATOM)
		(*T)->atom_htp.atom = S->atom_htp.atom;		//复制单个原子
	else {
    
    
		/*复制表头*/
		CopyGList(S->atom_htp.htp.hp, &((*T)->atom_htp.htp.hp));
		/*复制表尾*/
		CopyGList(S->atom_htp.htp.tp, &((*T)->atom_htp.htp.tp));
	}
	return OK;
}

Reference: Geng Guohua "Data Structure - Described in C Language (Second Edition)"

For more data structure content, follow my "Data Structure" column : https://blog.csdn.net/weixin_51450101/category_11514538.html?spm=1001.2014.3001.5482

Guess you like

Origin blog.csdn.net/weixin_51450101/article/details/122734677