您的位置:首页 > 理论基础 > 数据结构算法

看数据结构写代码(51) 广义表的头尾链式存储

2015-04-18 16:18 549 查看
广义表是一种非线性的数据结构。但如果广义表的每个元素都是原子,它就变成了线性表。广义表广泛地用于人工智能等领域的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(©,list);
printGList(copy);
destoryGList(&list);
return 0;
}
运行截图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息