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

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

2015-04-18 21:24 666 查看
广义表 的另一种 存储结构是 扩展线性链表存储表示,这种 存储结构的 根 节点 必 存在,并且 根节点的 表尾 为空,将 根节点的 表尾 放 在 表头 的 表尾 指针上。

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

具体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(©,list);
printGList(copy);
destoryGList(&list);
return 0;
}
运行截图:

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

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