码迷,mamicode.com
首页 > 其他好文 > 详细

看数据结构写代码(52) 广义表的扩展线性链表存储表示

时间:2015-04-19 09:00:12      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:广义表   广义表的扩展线性链表实现   广义表的扩展线性链表表示c语言描述   

广义表 的另一种 存储结构是 扩展线性链表存储表示,这种 存储结构的 根 节点 必 存在,并且 根节点的 表尾 为空,将 根节点的 表尾 放 在 表头 的 表尾 指针上。

这样 从 表头 一直 就可以 遍历 所有 同级 节点。

具体j结构 如下:

技术分享

例如 下面的 广义表 ,用 扩展线性链表 表示为:

技术分享

技术分享

而 头尾 存储表示,是 把 表头 和 表尾 都放在 根节点 的 指针上。其存储结构如下:

技术分享技术分享

所以 其 实现 代码略有 不同,要 小心 处理

下面 上代码:

// GList2.cpp : 定义控制台应用程序的入口点。
//

// GList.cpp : 定义控制台应用程序的入口点。
//广义表的扩展线性链表存储方式

#include "stdafx.h"
#include <cstdlib>
#include <cstring>
#define MAX_SIZE 500
typedef char ATomType;
enum ElemTag{
	Tag_Atom,
	Tag_List,
};

enum E_State{
	E_State_Error = 0,
	E_State_Ok = 1,
};

typedef struct GLNode{
	ElemTag tag;
	union {
		ATomType data;//原子数据
		GLNode * hLink;//表头
	};
	GLNode * nextLink;//指向后继节点》。
}*GList;

void initGList(GList * list){
	*list = NULL;
}
//最简版的 subString,没有判断边界条件,效率最高
void subString(char * s,char * sub,int startIndex,int len){
	for (int i = 1; i < startIndex; i++,s++);
	for (int i = 0; i < len; i++) sub[i] = s[i];
	sub[len] = '\0';
}

//分离 出 表头 字符串.
void strSep(char * sub,char * hSub){
	int i =0;
	int k = 0;//左括号不匹配的个数
	int len = strlen(sub);
	for (;i < len; i++){
		if (sub[i] == '(') k++;
		if (sub[i] == ')') k--;
		if (sub[i] == ',' && k == 0)break;
	}
	if (i < len){
		subString(sub,hSub,1,i);
		subString(sub,sub,i+2,len-i-1);
	}
	else{//表头即为 sub
		subString(sub,hSub,1,len);
		sub[0] = '\0';
	}
	//printf("%s\t%s\n",hSub,sub);
}

void createGList(GList * list,char * string){
	GList p = *list = (GList)malloc(sizeof(GLNode));
	if (strcmp(string,"()") == 0){
		p->tag = Tag_List;
		p->hLink = p->nextLink = NULL;
	}
	else {
		int len = strlen(string);
		if (len == 1){//原子结构
			p->tag = Tag_Atom;
			p->nextLink = NULL;
			p->data = string[0];
		}
		else{
			p->nextLink = NULL;
			p->tag = Tag_List;
			char sub[MAX_SIZE];
			subString(string,sub,2,len-2);//去掉 最外层 ()
			char hSub[MAX_SIZE];
			strSep(sub,hSub);
			createGList(&p->hLink,hSub);
			p = p->hLink;
			//创建头结点后继
			while (sub[0] != '\0'){
				strSep(sub,hSub);
				createGList(&p->nextLink,hSub);
				p = p->nextLink;
			}
		}
	}
}
//后序释放..
void destoryGList(GList * list){
	if (*list != NULL){
		if ((*list)->tag != Tag_Atom){
			destoryGList(&(*list)->hLink);
		}
		destoryGList(&(*list)->nextLink);
		free(*list);
		*list = NULL;
	}
}

void copyList(GList * to,GList from){
	if (from != NULL){
		GList p = *to = (GList)malloc(sizeof(GLNode));
		p->tag = from->tag;
		if (from->tag == Tag_Atom){
			p->data = from->data;
		}
		else{
			copyList(&(*to)->hLink,from->hLink);
		}
		copyList(&(*to)->nextLink,from->nextLink);
	}
	else{//少加了下面的两句
		*to = NULL;
	}
}


//求广义表的长度 
//list = (a1,a2,a3....an), 长度 为n
int listLen(GList list){
	int len = 0;
	list = list->hLink;
	while (list != NULL){
		len ++;
		list = list->nextLink;
	}
	return len;
}
//求广义表的深度 ,广义表括弧的重数..
//list = (a1,a2,a3....an), 深度为:max(listDepth(a1),listDepth(a2),listDepth(a3)...)+1
int listDepth(GList list){
	if (list == NULL || list->tag == Tag_List && list->hLink == NULL){
		return 1;
	}
	else if(list->tag == Tag_Atom){
		return 0;
	}
	else
	{
		int max = 0;
		GList p = list->hLink;
		for (;p != NULL; p=p->nextLink){
			int depth = listDepth(p);
			if (max < depth){
				max = depth;
			}
		}
		return max +1;
	}
}

bool isListEmpty(GList list){
	return list == NULL ? true : false;
}

GList getHead(GList list){
	return list == NULL ? NULL : list->hLink;
}

GList getTail(GList list){
	return list == NULL ? NULL : list->hLink->nextLink;
}
//插入一个元素在表头
GList insertFirst(GList * list,ATomType data){
	//错误
	//GList newList = (GList) malloc(sizeof(GLNode));
	//newList->tag = Tag_List;
	//newList->nextLink = NULL;
	GList  head = (GList) malloc(sizeof(GLNode));
	//newList->hLink = head;
	head->tag = Tag_Atom;
	head->data = data;
	GList  p = (*list)->hLink;
	(*list)->hLink = head;
	head->nextLink = p;;
	//*list = newList;
	return *list;
}

void deleteFirst(GList * list){
	GList  p = (*list)->hLink->nextLink;
	(*list)->hLink->nextLink = NULL;
	destoryGList(list);
	*list = p;
}

void printGList(GList list){
	if (list != NULL){
		if (list->tag == Tag_Atom){//原子节点 没有头节点..
			printf("%c",list->data);
		}
		else{
			printGList(list->hLink);
		}
		printGList(list->nextLink);
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	printf("-----------------创建广义表----------------\n");
	printf("请输入广义表,用() 表示表类型,用,分割表成员:");
	char s[MAX_SIZE];
	scanf("%s",s);
	GList list;
	createGList(&list,s);
	printGList(list);
	int len = listLen(list);
	int depth = listDepth(list);
	char * isEmpty = isListEmpty(list) ? "表为空" : "表不空";
	printf("\n表长为:%d,表深:%d,%s",len,depth,isEmpty);
	GList head = getHead(list);
	GList tail = getTail(list);
	//printf("\n-----------------表头----------------\n");
	//printGList(head);
	printf("\n-----------------表尾----------------\n");
	printGList(tail);
	printf("\n-----------------在表头插入一个元素----------------\n");
	insertFirst(&list,'z');
	printGList(list);
	printf("\n-----------------删除表头----------------\n");
	deleteFirst(&list);
	printGList(list);
	printf("\n-----------------拷贝广义表----------------\n");
	GList copy;
	copyList(&copy,list);
	printGList(copy);
	destoryGList(&list);
	return 0;
}
运行截图:

源码网盘地址:点击打开链接


技术分享

看数据结构写代码(52) 广义表的扩展线性链表存储表示

标签:广义表   广义表的扩展线性链表实现   广义表的扩展线性链表表示c语言描述   

原文地址:http://blog.csdn.net/fuming0210sc/article/details/45116677

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!