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

看数据结构写代码(51) 广义表

时间:2015-04-18 17:49:37      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:广义表c语言描述   广义表   广义表的头尾链式存储结构实现   

广义表是一种非线性的数据结构。但如果广义表的每个元素都是原子,它就变成了线性表。广义表广泛地用于人工智能等领域的LISP语言。

广义表一般记作 LS = (a1, a2, ···, an), n是它的长度,ai可以是单个元素(原子),也可以是广义表(子表),当广义表非空时,称第一个元素a1为LS的表头,称其余元素组成的表为LS的表尾。注意:表头是元素(可以是原子,也可以是广表),表尾一定是广义表。E=(a, E)是一个递归的表。D=(( ),(e),(a,(b,c,d)))是多层次的广义表,长度为3,深度为3。例:((a),a)的表头是(a),表尾是(a),((a))的表头是(a),表尾是( )

广义表的存储方式 有两种: 头尾链式存储,和扩展线性链表存储表示。

下面 给出 头尾链式 存储 表示 方式的 广义表的 操作:

// 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 GListNode{
	ElemTag tag;
	union {
		ATomType data;//原子数据
		struct{
			GListNode * hLink;
			GListNode * tLink;
		}ptr;
	};
}*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){
	if (strcmp(string,"()") == 0 ){
		*list = NULL;
	}
	else{
		int len = strlen(string);
		GList p = (*list) = (GList)malloc(sizeof(GListNode));
		if (len == 1){
			p->tag = Tag_Atom,p->data = string[0];
		}
		else{
			p->tag = Tag_List;
			char sub[MAX_SIZE];
			subString(string,sub,2,len-2);//去掉最外层 “()”
			char hSub[MAX_SIZE];//表头字符串.
			do{
				strSep(sub,hSub);
				createGList(&(p->ptr.hLink),hSub);//建立表头
				GList q = p;
				if (*sub != '\0'){//创建表尾
					p = (GList)malloc(sizeof(GListNode));
					p->tag = Tag_List;q->ptr.tLink = p;
				}
				else{
					p->ptr.tLink = NULL;
				}
			} while (*sub != '\0');
		}
	}
}
//后序释放..
void destoryGList(GList * list){
	if (*list != NULL){
		if ((*list)->tag == Tag_Atom){
			free(*list);
		}
		else{
			destoryGList(&(*list)->ptr.hLink);
			destoryGList(&(*list)->ptr.tLink);
			free(*list);
			*list = NULL;
		}
		//表头和 表尾 都释放完了。。最后 释放自己.
		//傻蛋。。异想天开。
		//free(*list);
		//*list = NULL;
	}
}

void copyList(GList * to,GList from){
	if (from == NULL){
		*to = NULL;
	}
	else {
		GList p = (*to) = (GList)malloc(sizeof(GListNode));
		if (from->tag == Tag_Atom){
			p->tag = Tag_Atom,p->data = from->data;
		}
		else{
			p->tag = Tag_List;
			copyList(&(p->ptr.hLink),from->ptr.hLink);
			copyList(&(p->ptr.tLink),from->ptr.tLink);
		}
	}
}


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

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

void deleteFirst(GList * list){
	GList  p = (*list)->ptr.tLink;
	(*list)->ptr.tLink = NULL;
	destoryGList(list);
	*list = p;
}

void printGList(GList list){
	if (list != NULL){
		if (list->tag == Tag_Atom){
			printf("%c\t",list->data);
		}
		else{
			printGList(list->ptr.hLink);
			printGList(list->ptr.tLink);
		}
	}
}


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;
}
运行截图:

技术分享

看数据结构写代码(51) 广义表

标签:广义表c语言描述   广义表   广义表的头尾链式存储结构实现   

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

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