数据结构学习随笔---广义表结点的两种方式C语言实现以及广义表的储存实现(笨蛋式)

#广义表简介
广义表是线性表的推广,也是一种基础的数据结构。广义表类似于数组,不同的是,广义表里面可以存储广义表,即储存单个元素或者多个元素组成的广义表。其中,单个元素称为原子广义表中的广义表称为子表,甚至子表的子表还可以是广义表。广义表内部类似于一种递归结构
广义表第一个元素称为表头,表头后面的称为表尾。其中,表头可以使原子或者广义表,表尾一定是广义表,哪怕是空表。

#广义表存储链表的两种结点方式

虽然广义表类似于数组,但是由于广义表储存的元素大小可能不一样(原子和子表),所以采用链表的方式进行储存,并且结点结构包括对原子的储存和子表的储存,还涉及到两种不同的结点结构。
##头尾链表存储表示
广义表的头尾链表存储
第一种就是图上所示的表示,有一个共同的tag标志用于区分原子和子表。子表有一个头指针和尾指针;原子有一个数据域。接下来就是代码实现:

//广义表的存储实现
//1.0 标志位
typedef enum MyEnum
{
	ATOM1,
	LIST1
}Tag;

//2.0 结点表示(头尾形式)
typedef struct GLNode
{
	Tag tag;
	union 
	{
		char data;
		struct 
		{
			struct GLNode *hp,*tp;
		}ptr;
	};
}*GList,GNode;

接下来是使用这种储存方式进行广义表的创建和储存,两种存储的元素都是{a,{c,s,l}}

//1.0 广义表的创建  头尾链表法
GList creatGlist(GList head) {
	//广义表C
	head = (GList)malloc(sizeof(GList));  //表结点类型指针 C是一个表头指针
	head->tag = LIST1;                     //初始化为广义表

	//表头原子‘a’
	head->ptr.hp = (GList)malloc(sizeof(GList));
	head->ptr.hp->tag = ATOM1;
	head->ptr.hp->data = 'a';  //表头原子

	 
	//表尾子表(c,s,l),是一个整体
	head->ptr.tp = (GList)malloc(sizeof(GList));  //表尾指针指向表尾,表尾一定是一个列表(可能是空列表),所以表尾指针相当于一个表头指针   
	head->ptr.tp->tag = LIST1;
	head->ptr.tp->ptr.hp = (GList)malloc(sizeof(GList));
	head->ptr.tp->ptr.tp = NULL;

	//开始存放下一个元素(c,s,l),其中c为表头,(s,l)为尾
	head->ptr.tp->ptr.hp->tag = LIST1;
	//C->ptr.tp->ptr.hp->ptr.hp = (GList)malloc(sizeof(GList));
	head->ptr.tp->ptr.hp->tag = ATOM1;
	head->ptr.tp->ptr.hp->data = 'c';
	head->ptr.tp->ptr.hp->ptr.tp = (GList)malloc(sizeof(GList));



	//存放's,l'
	head->ptr.tp->ptr.hp->ptr.tp->tag = LIST1;
	head->ptr.tp->ptr.hp->ptr.tp->ptr.hp = (GList)malloc(sizeof(GList));
	head->ptr.tp->ptr.hp->ptr.tp->ptr.hp->tag = ATOM1;
	head->ptr.tp->ptr.hp->ptr.tp->ptr.hp->data = 's';
	head->ptr.tp->ptr.hp->ptr.tp->ptr.tp = (GList)malloc(sizeof(GList));


	//存放'l'
	head->ptr.tp->ptr.hp->ptr.tp->ptr.tp->tag = LIST1;
	head->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp = (GList)malloc(sizeof(GList));
	head->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->tag = ATOM1;
    head->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->data = 'l';
	head->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.tp = NULL;

	return head;
}

接下来计算广义表的长度(注意广义表的长度和深度的区别)

//获取广义表的长度
int getLength(GList head)
{
	int number = 0;
	GList P = head;
	while (P)
	{
		number++;
		
		P = P->ptr.tp;

	}
	return number;
}

运行结果:
在这里插入图片描述
在运行时有时候出现这种情况,不知道哪位大佬能解答一下:
在这里插入图片描述

##第二种结点方式

在这里插入图片描述

这里把tp提取出来,相当于一个next指针。与第一种不同的是,这里的原子结点有了指向下一个结点的指针,而第一中原子与原子之间是相互独立的,通过表结点相互连接(这两种图在数据结构的相关书籍上应该都有,要画的话有点麻烦,原谅我偷懒_----)

代码实现:

//1.0.1  广义表的表示以及创建第二种表达方式
typedef enum
{
	ATOM,
	LIST

}Tag2;

typedef struct GLnode2
{
	Tag2 tag2;
	union 
	{
		char data;
		struct
		{
			struct GLnode2 *hp;
		}ptr;
	};
	struct  GLnode2 *tp;

}*GList2,GNode2;

接下来使用第二种结点结构进行广义表创建以及元素的储存:

GList2 creatGList2(GList2 head)
{
	//整个广义表 
	head = (GList2)malloc(sizeof(GList2));
	head->tag2 = LIST;

	//表头原子'a'
	head->ptr.hp = (GList2)malloc(sizeof(GList2));
	head->ptr.hp->tag2 = ATOM;
	head->ptr.hp->data = 'a';

	//整体的c,s,l 
	head->tp = (GList2)malloc(sizeof(GList2));
	head->tp->ptr.hp = (GList2)malloc(sizeof(GList2));
	head->tp->tag2 = LIST;
	head->tp->tp = NULL;



	//下一个元素c
	head->tp->ptr.hp->tag2 = ATOM;
	head->tp->ptr.hp->data = 'c';
	head->tp->ptr.hp->tp = (GList2)malloc(sizeof(GList2));

	//s,l;

	head->tp->ptr.hp->tp = (GList2)malloc(sizeof(GList2));
	head->tp->ptr.hp->tp->tag2 = ATOM;
	head->tp->ptr.hp->tp->data = 's';
	head->tp->ptr.hp->tp->tp = (GList2)malloc(sizeof(GList2));

	//l
	head->tp->ptr.hp->tp->tp->tag2 = ATOM;
	head->tp->ptr.hp->tp->tp->data = 'l';
	head->tp->ptr.hp->tp->tp = NULL;


	return head;

}

很明显,第二种方式相对于第一种显得精简很多。

长度:

//获取广义表的长度
int getLength2(GList2 get)
{
	int number = 0;
	while (get)
	{
		number++;

		get = get->tp;
	}
	return number;
}

运行结果:
在这里插入图片描述
上面是我学习数据结构广义表的时候的随笔,肯定有很多不知道的错误。希望大家指出,在后续我也将不断完善。上面也有从网上借鉴,如果有侵权或者不想在本文中出现的请联系我,谢谢大家!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值