数据结构之---C语言实现广义表头尾链表存储表示
//广义表的头尾链表存储表示
//杨鑫
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRLEN 40 )
typedef char SString[MAXSTRLEN+1];
typedef char AtomType; // 定义原子类型为字符型
typedef enum{
ATOM, LIST // ATOM==0:原子 LIST==1:子表
} ElemTag; typedef struct GLNode
{
ElemTag tag; // 公共部分,用于区分原子结点和表结点
union // 原子结点和表结点的联合部分
{
AtomType atom; // atom是原子结点的值域, AtomType由用户定义
struct
{
struct GLNode *hp,*tp;
}ptr; // ptr是表结点的指针域,prt.hp和ptr.tp分别指向表头和表尾
}a;
} *GList, GLNode; //初始化的广义表L
int InitGList(GList *L)
{
*L = NULL;
return 1;
} //销毁广义表L
void DestroyGList(GList *L)
{
GList q1,q2;
if(*L)
{
if((*L)->tag == ATOM)
{
free(*L);
*L = NULL;
}
else
{
q1 = (*L)->a.ptr.hp;
q2 = (*L)->a.ptr.tp;
free(*L);
*L = NULL;
DestroyGList(&q1);
DestroyGList(&q2); // 递归删除表头和表尾结点 }
}
} // 採用头尾链表存储结构,由广义表L复制得到广义表T。
int CopyGList(GList *T,GList L)
{
if(!L)
*T = NULL;
else
{
*T = (GList)malloc(sizeof(GLNode));
if(!*T)
exit(0);
(*T)->tag = L->tag;
if(L->tag == ATOM)
(*T)->a.atom = L->a.atom; // 复制单原子
else // 是表结点,则依次复制表头和表尾
{
CopyGList(&((*T)->a.ptr.hp), L->a.ptr.hp);
CopyGList(&((*T)->a.ptr.tp), L->a.ptr.tp); }
}
return 1;
} // 返回广义表的长度,即元素个数
int GListLength(GList L)
{
int len = 0;
if(!L)
return 0;
if(L->tag == ATOM)
return 1;
while(L)
{
L = L->a.ptr.tp;
len++;
}
return len;
} // 採用头尾链表存储结构,求广义表L的深度。 int GListDepth(GList L)
{
int max, dep;
GList pp; if(!L)
return 1; // 空表深度为1
if(L->tag == ATOM)
return 0; // 原子深度为0
for(max = 0, pp = L; pp; pp = pp->a.ptr.tp)
{
// 递归求以pp->a.ptr.hp为头指针的子表深度
dep = GListDepth(pp->a.ptr.hp);
if(dep > max)
max = dep;
}
return max+1; // 非空表的深度是各元素的深度的最大值加1
} // 判定广义表是否为空
int GListEmpty(GList L)
{
if(!L)
return 1;
else
return 0;
} // 取广义表L的头
GList GetHead(GList L)
{
GList h,p; if(!L)
{
printf("空表无表头!\n");
exit(0);
}
p = L->a.ptr.tp;
L->a.ptr.tp = NULL;
CopyGList(&h,L);
L->a.ptr.tp = p;
return h;
} // 取广义表L的尾
GList GetTail(GList L)
{
GList t;
if(!L)
{
printf("空表无表尾!\n");
exit(0);
}
CopyGList(&t, L->a.ptr.tp);
return t;
} // 插入元素e作为广义表L的第一元素(表头,也可能是子表)
int InsertFirst_GL(GList *L,GList e)
{
GList p = (GList)malloc(sizeof(GLNode));
if(!p)
exit(0);
p->tag = LIST;
p->a.ptr.hp = e;
p->a.ptr.tp = *L;
*L = p;
return 1;
} // 删除广义表L的第一元素,并用e返回其值
int DeleteFirst_GL(GList *L,GList *e)
{
GList p;
*e = (*L)->a.ptr.hp;
p = *L;
*L = (*L)->a.ptr.tp;
free(p);
return 1;
} // 利用递归算法遍历广义表L
void Traverse_GL(GList L,void(*v)(AtomType))
{
if(L)
if(L->tag == ATOM)
v(L->a.atom);
else
{
Traverse_GL(L->a.ptr.hp,v);
Traverse_GL(L->a.ptr.tp,v);
}
} // 生成一个其值等于chars的串T
int StrAssign(SString T,char *chars)
{
int i;
if(strlen(chars) > MAXSTRLEN)
return 0;
else
{
T[0] = strlen(chars);
for(i = 1; i <= T[0]; i++)
T[i] = *(chars + i - 1);
return 1;
}
} // 由串S复制得串T
int StrCopy(SString T, SString S)
{
int i;
for(i = 0; i <= S[0]; i++)
T[i] = S[i];
return 1;
} // 若S为空串,则返回1,否则返回0
int StrEmpty(SString S)
{
if(S[0] == 0)
return 1;
else
return 0;
} // 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
int StrCompare(SString S,SString T)
{
int i;
for(i = 1; i <= S[0] && i <= T[0]; ++i)
if(S[i] != T[i])
return S[i] - T[i];
return S[0]-T[0];
} // 返回串的元素个数
int StrLength(SString S)
{
return S[0];
} // 将S清为空串
int ClearString(SString S)
{
S[0] = 0; // 令串长为零
return 1;
} // 用Sub返回串S的第pos个字符起长度为len的子串。
int SubString(SString Sub,SString S,int pos,int len)
{
int i;
if(pos < 1 || pos >S[0] || len < 0 || len > S[0]-pos+1)
return 0;
for(i = 1; i <= len; i++)
Sub[i]=S[pos+i-1];
Sub[0] = len;
return 1;
} // 将非空串str切割成两部分:hsub为第一个','之前的子串,str为之后的子串
void sever(SString str,SString hstr)
{
int n,i, k;
SString ch,c1,c2,c3;
n = StrLength(str);
StrAssign(c1,",");
StrAssign(c2,"(");
StrAssign(c3,")");
SubString(ch,str,1,1);
for(i = 1,k = 0;i <= n && StrCompare(ch,c1) || k != 0; ++i)
{
SubString(ch, str, i, 1);
if(!StrCompare(ch, c2))
++k;
else if(!StrCompare(ch,c3))
--k;
}
if(i <= n)
{
SubString(hstr, str, 1, i-2);
SubString(str, str, i, n - i + 1);
}
else
{
StrCopy(hstr, str);
ClearString(str);
}
} // 广义表L。设emp="()"
int CreateGList(GList *L, SString S)
{
SString sub,hsub,emp;
GList p,q; StrAssign(emp,"()");
if(!StrCompare(S, emp))
*L = NULL; // 创建空表
else
{
*L = (GList)malloc(sizeof(GLNode));
if(!*L) // 建表结点
exit(0);
if(StrLength(S) == 1) // S为单原子
{
(*L)->tag = ATOM;
(*L)->a.atom = S[1]; // 创建单原子广义表
}
else
{
(*L)->tag = LIST;
p = *L;
SubString(sub, S, 2, StrLength(S)-2); // 脱外层括号
do
{ // 反复建n个子表
sever(sub, hsub); // 从sub中分离出表头串hsub
CreateGList(&p->a. ptr. hp, hsub);
q = p;
if(!StrEmpty(sub)) // 表尾不空
{
p = (GLNode *)malloc(sizeof(GLNode));
if(!p)
exit(0);
p->tag = LIST;
q->a.ptr.tp = p;
}
}while(!StrEmpty(sub));
q->a.ptr.tp = NULL;
}
}
return 1;
} // 打印原子
void visit(AtomType e)
{
printf("%c ", e);
} int main()
{
// 广义表的表示形式是,空表:(),单原子:a,表:(a,(b),c,(d,(e)))
char p[80] = {"(a,(b),c,(d,(e)))"};
SString t;
GList L,m; InitGList(&L);
InitGList(&m);
printf("空广义表L的深度 = %d\nL是否空?%d(1:是 0:否)\n\n",
GListDepth(L), GListEmpty(L));
StrAssign(t, p);
CreateGList(&L, t); // 创建广义表
printf("\n广义表L的长度 = %d\n", GListLength(L));
printf("广义表L的深度 = %d \nL是否空?%d(1:是 0:否)\n",
GListDepth(L), GListEmpty(L));
printf("遍历广义表L:\n");
Traverse_GL(L, visit);
printf("\n\n复制广义表m = L\n");
CopyGList(&m, L);
printf("广义表m的长度 = %d\n", GListLength(m));
printf("广义表m的深度 = %d\n", GListDepth(m));
printf("遍历广义表m:\n");
Traverse_GL(m,visit);
DestroyGList(&m);
m = GetHead(L);
printf("\n\nm是L的表头,遍历广义表m:\n");
Traverse_GL(m, visit);
DestroyGList(&m);
m = GetTail(L);
printf("\n\nm是L的表尾,遍历广义表m:\n");
Traverse_GL(m,visit);
InsertFirst_GL(&m, L);
printf("\n\n插入L为m的表头。遍历广义表m:\n");
Traverse_GL(m,visit);
printf("\n\n删除m的表头。遍历广义表m:\n");
DestroyGList(&L);
DeleteFirst_GL(&m, &L);
Traverse_GL(m, visit);
printf("\n");
DestroyGList(&m);
return 0;
}
数据结构之---C语言实现广义表头尾链表存储表示的更多相关文章
- 数据结构之---C++语言实现图的十字链表存储表示
近期一直忙着考研复习,非常久都没有更新博客了.今天写一篇数据结构的存储. //有向图的十字链表存储表示 //杨鑫 #include <iostream> #include <cstd ...
- 数据结构C语言版 有向图的十字链表存储表示和实现
/*1wangxiaobo@163.com 数据结构C语言版 有向图的十字链表存储表示和实现 P165 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h> ...
- C语言实现线性表(链式存储方式)
#include <stdio.h> #include <stdlib.h> //提供malloc()原型 typedef struct LNode *List; typede ...
- 数据结构(C语言版)---线性表链式存储表示
1.单链表:线性表的链式存储. 1)特点:用一组任意的存储单元存储数据元素(存储单元可以连续,也可以不连续),逻辑上相邻的元素存储位置不一定相邻. 2)结点包括两个域:数据域(存储数据元素信息).指针 ...
- 数据结构算法C语言实现(十九)--- 5.5&5.6&5.7广义表
一.简述 传说Lisp的基本数据结构就是广义表,广义表也是具有典型递归属性的数据结构,此外,由于建表要处理字符串,用C语言处理起来也是一脸懵逼.....最后自己还想写一个将广义表还原成字符串的函数,一 ...
- 数据结构(C语言第2版)-----数组,广义表,树,图
任何一个算法的设计取决于选定的数据结构,而算法的实现依赖于采用的存储结构. 之前线性表的数据元素都是非结构的原子类型,元素的值是不可再分的.下面学习的这两个线性表是很特殊的,其中数据元素本身也可能是一 ...
- javascript实现数据结构:广义表
原文:javascript实现数据结构:广义表 广义表是线性表的推广.广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构. 广义表一般记作: LS = (a1, a2, ..., an ...
- 【C/C++】实现数据结构广义表
1. 广义表的定义 每个元素可以为Atom,原子,也可以为线性表. 线性表的推广.线性表元素有唯一的前驱和后继,为线性表,而广义表是多层次的线性表 表头:第一个元素,可能是 ...
- 数据结构28:广义表及M元多项式
广义表,又称为列表.记作: LS = (a1,a2,…,an) ;( LS 为广义表的名称, an 表示广义表中的数据). 广义表可以看作是线性表的推广.两者区别是:线性表中的数据元素只能表示单个数据 ...
随机推荐
- JavaScript中变速运动的数学模型构建
AB两地直线距离相距为S,机器人β从A点向B点行进.已知机器人β的每间隔固定时间行进一段路程,其下次行进的距离为当前距离B点路程的1/q(q为正整数),求机器人第n次行进距离的表达式an以及前n项和公 ...
- jFinal基于maven简单的demo
JFinal 是基于Java 语言的极速 web 开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java语言所有优势的同时再拥有ruby.py ...
- 5.23Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分
作者:https://www.cnblogs.com/lyjin/p/6389349.html PO:持久对象(persistent object):---po就是在Object/Relation M ...
- System.net.mail发送电子邮件
之前做的实现发送邮件的功能,基于System.net.mail,在本地测试是可以发送邮件的,发布到服务器上发送不了邮件,后来发现STMP默认使用25端口收发邮件,服务器封掉25了端口,导致发送邮件失败 ...
- 【java并发】(1)深入理解volatile关键字
volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...
- js 字符串 处理方法
charAt() 返回指定索引位置的字符 charCodeAt() 返回指定索引位置字符的 Unicode 值 concat() 连接两个或多个字符串,返回连接后的字符串 fromCharCode() ...
- Appium Android 获取包名和 Activity 的几种方法 (转)
本文档主要记录“获取包名和 Activity 的方法”,用于自动化测试时启动APP.以下方法主要来源于网络和社区同学的贡献,特此感谢! 1. 方法一: pm list package查看包名 adb ...
- C#连接Oracle数据库的方法(System.Data.OracleClient、Oracle.DataAccess.Client也叫ODP.net、Oracle.ManagedDataAccess.dll)
官方下载地址(ODP.net)(中文):http://www.oracle.com/technetwork/cn/topics/dotnet/downloads/index.html 官方下载地址(O ...
- jsp 判断当前时间是否符合设置的时间条件
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- 深度遍历DFS---树
一.二叉树的深度 题目: 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,nul ...