文章目录

  • 一、定义
  • 二、结构
  • 三、常用操作
  • 结语
  • 附录

一、定义

广义表是线性表的推广,也有人称其为列表(lists,用复数形式以示与统称的表list的区别)。

二、结构

#define AtomType int  //原子类型
/*
广义表的结点标记
HEAD:表示表头结点
ATOM:表示原子结点
CHILDLIST:表示子表结点
*/
typedef enum{HEAD,ATOM,CHILDLIST}ElemTag;//广义表的结点
typedef struct GLNode
{ElemTag tag; //结点标记union //联合体{AtomType atom; //原子数据(如果该结点是原子结点,则使用该项)struct GLNode *hp; //表结点的表头指针(如果该结点是子表结点,则使用该项),指向子表的表头结点};struct GLNode *tp; //表尾指针(因为广义表的结点只有表头和表尾,所以这里的表尾指针相当于线性链表的next,指向下一个元素结点)
}GLNode;typedef GLNode* GenList; //广义表

三、常用操作

初始化

//广义表的初始化
void InitGenList(GenList &gl)
{gl = NULL;
}

创建广义表

//创建广义表:通过字符串str来创建广义表gl
void CreateGenList(GenList &gl, char *str)
{int n = strlen(str);//求解字符串长度//存储表内元素char *sub = (char *)malloc(sizeof(char) * (n-2));//存储表头char *hsub = (char *)malloc(sizeof(char) * (n-2));assert(sub!=NULL && hsub!=NULL);//"1,2,3"//去掉sub左右两边的括号strncpy(sub,str+1,n-2); sub[n-2] = '\0';//加上结束符//判断广义表是否为空if(gl == NULL){//为空//创建头结点(广义表的第一个结点为头结点,其余都为尾结点)gl = (GLNode*)malloc(sizeof(GLNode));assert(gl != NULL);gl->tag = HEAD; //结点标记为头结点gl->hp = gl->tp = NULL; //把子表指针和尾指针都指向空}GLNode *p = gl; //为了不丢失gl的指向,定义一个指针来操作//求子串长度,当sub长度不为零时,说明广义表还未创建完成while(strlen(sub) != 0){//采用尾插法,在后面插入结点/*1、创建一个结点2、让p所指结点的尾指针指向新建的结点3、让p指向新建结点*/p = p->tp = (GLNode*)malloc(sizeof(GLNode));assert(p != NULL);p->hp = p->tp = NULL;//将新建结点的子表指针和尾指针都赋空//"1,2,3"  ==>  "1"  hsub="1", sub="2,3";//"(1,2),3,4" ==> hsub="(1,2)" sub="3,4"if(sever(sub,hsub))//sever函数分离表头,并将表头存入hsub中{//分离成功//对分离出来的表头进行判断,是否包含括号if(hsub[0] == '('){//是//说明要创建的结点是子表类型p->tag = CHILDLIST;//设置子表标记CreateGenList(p->hp,hsub);//在p的表头结点处,创建hsub子表}else{//否//说明要创建的结点是原子类型p->tag = ATOM;//设置原子标记p->atom = atoi(hsub);//将表头字符串转换成整型数据,赋值给原子数据}}}
}//广义表表头分割函数,将sub中的表头分割到hsub中
bool sever(char *sub, char *hsub)
{//判断sub是否为空if(*sub=='\0' || strcmp(sub,"()")==0){//是 情况:""  或  "()"hsub[0] = '\0';//将hsub赋空return true;}int n = strlen(sub);//求sub的长度int i=0;char ch = sub[0];//获取第一个字符int k = 0;//表示括号的信息/*当sub还没遍历完成且还未检测到括号外的逗号,继续遍历注:当检测到括号外的逗号时,说明找到表头分割点,如:"(1,2),3,4" 表头即为(1,2)*/while(i<n && (ch!=','|| k!=0)){//判断是否运到左括号if(ch == '(')k++;//k++表示进入一层括号else if(ch == ')')//判断是否遇到右括号k--; //k--表示退出一层括号//获取下一个元素i++;ch = sub[i];}//判断是否是因为检测到括号外的逗号而结束的if(i < n){//是//在i位置截断,前面部分就是表头sub[i] = '\0';//将取得的表头放入hsub中strcpy(hsub,sub);//更新sub的值:此时的sub应该去掉表头hsubstrcpy(sub,sub+i+1);}else if(k != 0) //判断是否是因为内部括号不匹配return false;//是,分割失败else//判断是否是因为i>=n而结束{//是,情况 "(1,2)"  ==> hsub ="(1,2)"  sub = ""//说明sub整个就是表头strcpy(hsub,sub);//把sub整个赋值给hsubsub[0] = '\0';//sub赋给hsub后,此时sub为空}return true;
}

提取广义表内的元素

//将整数转换成字符串
void NumToStr(int num,  char* str,int& i)
{char temp[25];itoa(num, temp, 10);for(unsigned j=0;j<strlen(temp);++j)str[i++]=temp[j];
}/*  以字符串形式取出广义表内元素:如(1,(2,3)) 取得1,(2,3)
*/void GetGenList(GenList gl,char* str,int& i)
{//获取从首结点到最后一个结点的元素GLNode *p = gl->tp;  //当还未遍历到最后一个结点,一直进行遍历while(p != NULL) {//对结点类型进行判断if(p->tag == ATOM){//结点类型为原子类型// char temp[25];//    itoa(p->atom, temp, 10);//   for(unsigned j=0;j<strlen(temp);++j)//        str[i++]=temp[j];NumToStr(p->atom, str,i);//将数字转换成字符串存入str中if(p->tp != NULL)//判断该结点后面是否还有结点str[i++]=',';p = p->tp;//下移}else if(p->tag == CHILDLIST){//结点类型为子表str[i++]='(';GetGenList(p->hp,str,i);//从子表的表头指针开始对子表进行遍历str[i++]=')';if(p->tp != NULL)//判断该结点后面是否还有结点str[i++]=',';p = p->tp;//子表遍历完成后下移}}
}//将广义表转换成字符串形式:如(1,(2,3))   type:0 输出原子结点  type:1 输出表
char* GetGenListStr(GenList gl,int type)
{int i=0;char* str=(char*)malloc(sizeof(char)*1000);//str[i++]='(';//左括号if(type==0){       NumToStr(gl->atom, str,i); //将数字转换成字符串   }else{GetGenList(gl,str,i);//会多一个逗号}    //str[i++]=')';//右括号str[i]='\0';return str;
}

取首元素

//取首元素
char* GetHead(GenList gl)
{//判断首元素的结点类型if(gl->tp->tag==ATOM) //原子类型则传入该原子结点地址return GetGenListStr(gl->tp,0);else //子表类型则传入子节点的首地址return GetGenListStr(gl->hp,1);
}

取尾元素

//取尾元素
char* GetTail(GenList gl)
{GLNode *p=gl->tp;if(p->tp!=NULL)//判断是否存在尾元素{//存在//取尾元素(取后面的一串值)return GetGenListStr(p,1);}return NULL;
}

取最后一个元素

//取最后一个元素
char* GetLast(GenList gl)
{GLNode *p=gl->tp;while(p->tp!=NULL)p=p->tp;//判断首元素的结点类型if(p->tag==ATOM)//原子类型则传入该原子结点地址return GetGenListStr(p,0);else   //子表类型则传入子节点的首地址return GetGenListStr(p->hp,1);}

打印广义表

//打印广义表
void ShowGenList(GenList gl)
{//调用GetGenListStr函数将广义表转换成字符串printf("(%s)",GetGenListStr(gl,1));
}

判断广义表是否为空

//判断广义表是否为空
bool GenListEmpty(GenList gl)
{return gl->tp==NULL; //判断表头结点尾指针的指向是否为空
}

求广义表的长度

//求解广义表的长度
int  GenListLength(GenList gl)
{int length = 0;//记录长度GLNode *p = gl->tp;//从头结点的下一个结点开始统计(因为头结点不存数据)//当广义表还有元素,就继续遍历while(p != NULL){length++;//运到结点长度就加一p = p->tp;//后移}return length; //返回广义表长度
}

求广义表深度

//求解广义表的深度
int  GenListDepth(GenList gl)
{//判断广义表是否为空if(gl->tp == NULL)return 1;//空表深度为1GLNode *p = gl->tp; //指向头结点的下一个结点int maxdepth = 0; //记录深度int dep;//当广义表还未遍历完成,就一直遍历求取深度while(p != NULL){//判断结点类型是否为子表结点if(p->tag == CHILDLIST){//为子表结点//求取子表的深度dep = GenListDepth(p->hp);if(dep > maxdepth)//判断此时求得的深度是否比当前的最大深度大maxdepth =dep;//是,将dep赋给maxdepth}p = p->tp;//后移}return maxdepth+1;//返回深度(该层的深度=该层以下的最大深度+加上当前层的深度1)
}

复制广义表

//广义表的复制:gl复制到T
void CopyGenList(GenList gl,GenList &T)
{//判断广义表是否为空if(gl == NULL){//为空return;}//如果原来的广义表T已经存放数据if(T!=NULL){DestroyGenList(T);}//创建头结点(广义表的第一个结点为头结点,其余都为尾结点)T = (GLNode*)malloc(sizeof(GLNode));assert(T != NULL);T->tag = gl->tag; //结点标记为头结点T->hp = gl->hp;T->tp = gl->tp; //把子表指针和尾指针都指向空//由头结点指向下一个结点(头结点不存放数据)GLNode *p = gl->tp; //为了不丢失gl的指向,定义一个指针来操作GLNode *q = T; //为了不丢失T的指向,定义一个指针来操作//当还未遍历到最后一个结点,一直进行遍历while(p != NULL) {//创建结点q = q->tp = (GLNode*)malloc(sizeof(GLNode));assert(q != NULL);q->tag = p->tag; //结点标记为头结点q->hp = q->tp = NULL;//将新建结点的子表指针和尾指针都赋空//对结点类型进行判断if(p->tag == ATOM){//结点类型为原子类型q->atom =p->atom;//赋值p = p->tp;//下移}else if(p->tag == CHILDLIST){//结点类型为子表CopyGenList(p->hp,q->hp);//从子表的表头指针开始对子表进行遍历p = p->tp;//子表遍历完成后下移}}
}

首插

//插入元素str( 广义表的字符表示,如:((1,2),3)  )作为广义表的第一元素
void InsertFirstGenList(GenList &gl, char *str)
{GenList t;InitGenList(t);CreateGenList(t, str);//由头结点指向下一个结点(头结点不存放数据)GLNode *p = t->tp;//往后移动,一直移动到最后一个结点while(p->tp != NULL) {p=p->tp;}//将新创建的广义表t放到gl的前面p->tp=gl->tp;//将gl的头结点连上广义表tgl->tp=t->tp;free(t);//t的头结点无用,释放
}

首删

//删除广义表第一个位置的元素
void DeleteFirstGenList(GenList &gl,char* & str)
{GenList t;InitGenList(t);t=gl->tp; //将第一个元素地址传给t//将第一个元素从广义表中断开gl->tp=gl->tp->tp;//判断要释放的结点是什么类型if(t->tag==CHILDLIST){//子表结点//保存要删除的值str=GetGenListStr(t->hp,1);//释放子表DestroyGenList(t->hp);}else if(t->tag==ATOM){//原子结点//保存值str=GetGenListStr(t,0);}free(t);
}

清空广义表

//清空广义表
void ClearGenList(GenList &gl)
{//由头结点指向下一个结点(头结点不存放数据)GLNode *p = gl->tp;//当还未遍历到最后一个结点,一直进行遍历while(p != NULL) {//对结点类型进行判断if(p->tag == ATOM){//结点类型为原子类型gl->tp =p->tp;//将原子结点从广义表中取下free(p); //释放原子结点的内存空间p = gl->tp;//指向下一个结点}else if(p->tag == CHILDLIST){//结点类型为子表ClearGenList(p->hp);//从子表的表头指针开始对子表进行清空p = p->tp;//子表遍历完成后下移}}}

销毁广义表

//销毁广义表
void DestroyGenList(GenList &gl)
{//清空广义表ClearGenList(gl);free(gl);//释放广义表gl= NULL;
}

结语

对广义表的介绍就到这里啦,希望这篇文章能给予你一些帮助,感谢各位人才的:点赞、收藏和评论,我们下次见。

附录

以下提供测试代码

GenList.h

#pragma once#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<assert.h>
#include<stdlib.h>#define AtomType int  //原子类型
/*
广义表的结点标记
HEAD:表示表头结点
ATOM:表示原子结点
CHILDLIST:表示子表结点
*/
typedef enum{HEAD,ATOM,CHILDLIST}ElemTag;//广义表的结点
typedef struct GLNode
{ElemTag tag; //结点标记union //联合体{AtomType atom; //原子数据(如果该结点是原子结点,则使用该项)struct GLNode *hp; //表结点的表头指针(如果该结点是子表结点,则使用该项),指向子表的表头结点};struct GLNode *tp; //表尾指针(因为广义表的结点只有表头和表尾,所以这里的表尾指针相当于线性链表的next,指向下一个元素结点)
}GLNode;typedef GLNode* GenList; //广义表void InitGenList(GenList &gl);
void CreateGenList(GenList &gl, char *str);
bool sever(char *sub, char *hsub);///
char* GetGenListStr(GenList gl,int type);
char* GetHead(GenList gl);
char* GetTail(GenList gl);
char* GetLast(GenList gl);
void ShowGenList(GenList gl);
bool GenListEmpty(GenList gl);
int  GenListLength(GenList gl);
int  GenListDepth(GenList gl);
void CopyGenList(GenList gl,GenList &T);
void InsertFirstGenList(GenList &gl, char *str);
void DeleteFirstGenList(GenList &gl,char* &str);
void ClearGenList(GenList &gl);
void DestroyGenList(GenList &gl);

GenList.cpp

//广义表#include"GenList.h"//广义表的初始化
void InitGenList(GenList &gl)
{gl = NULL;
}//char *ga = "(1,2,3)";
//char *gb = "(1,(2,3))";
//char *gc = "(1,(2),3)";
//char *gd = "((1,2),3)";
//char *gd = "((1,2,3))";
//char *gd = "()";
//char *ge = "(1,(2,(3,4)),5)";//创建广义表:通过字符串str来创建广义表gl
void CreateGenList(GenList &gl, char *str)
{int n = strlen(str);//求解字符串长度//存储表内元素char *sub = (char *)malloc(sizeof(char) * (n-2));//存储表头char *hsub = (char *)malloc(sizeof(char) * (n-2));assert(sub!=NULL && hsub!=NULL);//"1,2,3"//去掉sub左右两边的括号strncpy(sub,str+1,n-2); sub[n-2] = '\0';//加上结束符//判断广义表是否为空if(gl == NULL){//为空//创建头结点(广义表的第一个结点为头结点,其余都为尾结点)gl = (GLNode*)malloc(sizeof(GLNode));assert(gl != NULL);gl->tag = HEAD; //结点标记为头结点gl->hp = gl->tp = NULL; //把子表指针和尾指针都指向空}GLNode *p = gl; //为了不丢失gl的指向,定义一个指针来操作//求子串长度,当sub长度不为零时,说明广义表还未创建完成while(strlen(sub) != 0){//采用尾插法,在后面插入结点/*1、创建一个结点2、让p所指结点的尾指针指向新建的结点3、让p指向新建结点*/p = p->tp = (GLNode*)malloc(sizeof(GLNode));assert(p != NULL);p->hp = p->tp = NULL;//将新建结点的子表指针和尾指针都赋空//"1,2,3"  ==>  "1"  hsub="1", sub="2,3";//"(1,2),3,4" ==> hsub="(1,2)" sub="3,4"if(sever(sub,hsub))//sever函数分离表头,并将表头存入hsub中{//分离成功//对分离出来的表头进行判断,是否包含括号if(hsub[0] == '('){//是//说明要创建的结点是子表类型p->tag = CHILDLIST;//设置子表标记CreateGenList(p->hp,hsub);//在p的表头结点处,创建hsub子表}else{//否//说明要创建的结点是原子类型p->tag = ATOM;//设置原子标记p->atom = atoi(hsub);//将表头字符串转换成整型数据,赋值给原子数据}}}
}//"1,2,3"  ==>    hsub="1", sub="2,3";
//"(1,2),3,4" ==> hsub="(1,2)" sub="3,4"//"" "()"//"(1,2)"  ==> hsub ="(1,2)"  sub = ""
//广义表表头分割函数,将sub中的表头分割到hsub中
bool sever(char *sub, char *hsub)
{//判断sub是否为空if(*sub=='\0' || strcmp(sub,"()")==0){//是 情况:""  或  "()"hsub[0] = '\0';//将hsub赋空return true;}int n = strlen(sub);//求sub的长度int i=0;char ch = sub[0];//获取第一个字符int k = 0;//表示括号的信息/*当sub还没遍历完成且还未检测到括号外的逗号,继续遍历注:当检测到括号外的逗号时,说明找到表头分割点,如:"(1,2),3,4" 表头即为(1,2)*/while(i<n && (ch!=','|| k!=0)){//判断是否运到左括号if(ch == '(')k++;//k++表示进入一层括号else if(ch == ')')//判断是否遇到右括号k--; //k--表示退出一层括号//获取下一个元素i++;ch = sub[i];}//判断是否是因为检测到括号外的逗号而结束的if(i < n){//是//在i位置截断,前面部分就是表头sub[i] = '\0';//将取得的表头放入hsub中strcpy(hsub,sub);//更新sub的值:此时的sub应该去掉表头hsubstrcpy(sub,sub+i+1);}else if(k != 0) //判断是否是因为内部括号不匹配return false;//是,分割失败else//判断是否是因为i>=n而结束{//是,情况 "(1,2)"  ==> hsub ="(1,2)"  sub = ""//说明sub整个就是表头strcpy(hsub,sub);//把sub整个赋值给hsubsub[0] = '\0';//sub赋给hsub后,此时sub为空}return true;
}//将整数转换成字符串
void NumToStr(int num,  char* str,int& i)
{char temp[25];itoa(num, temp, 10);for(unsigned j=0;j<strlen(temp);++j)str[i++]=temp[j];
}/*  将广义表转换成字符串形式:如(1,(2,3)) 但是由于递归获取,该函数转换后在结尾会多一个逗号,所以使用GetGenListStr对其进行包装消去逗号
*/void GetGenList(GenList gl,char* str,int& i)
{//获取从首结点到最后一个结点的元素GLNode *p = gl->tp;  //当还未遍历到最后一个结点,一直进行遍历while(p != NULL) {//对结点类型进行判断if(p->tag == ATOM){//结点类型为原子类型// char temp[25];//    itoa(p->atom, temp, 10);//   for(unsigned j=0;j<strlen(temp);++j)//        str[i++]=temp[j];NumToStr(p->atom, str,i);//将数字转换成字符串存入str中if(p->tp != NULL)//判断该结点后面是否还有结点str[i++]=',';p = p->tp;//下移}else if(p->tag == CHILDLIST){//结点类型为子表str[i++]='(';GetGenList(p->hp,str,i);//从子表的表头指针开始对子表进行遍历str[i++]=')';if(p->tp != NULL)//判断该结点后面是否还有结点str[i++]=',';p = p->tp;//子表遍历完成后下移}}
}//将广义表转换成字符串形式:如(1,(2,3))   type:0 输出原子结点  type:1 输出表
char* GetGenListStr(GenList gl,int type)
{int i=0;char* str=(char*)malloc(sizeof(char)*1000);//str[i++]='(';//左括号if(type==0){       NumToStr(gl->atom, str,i); //将数字转换成字符串   }else{GetGenList(gl,str,i);//会多一个逗号}    //str[i++]=')';//右括号str[i]='\0';return str;
}//取首元素
char* GetHead(GenList gl)
{//判断首元素的结点类型if(gl->tp->tag==ATOM) //原子类型则传入该原子结点地址return GetGenListStr(gl->tp,0);else //子表类型则传入子节点的首地址return GetGenListStr(gl->hp,1);
}//取尾元素
char* GetTail(GenList gl)
{GLNode *p=gl->tp;if(p->tp!=NULL)//判断是否存在尾元素{//存在//取尾元素(取后面的一串值)return GetGenListStr(p,1);}return NULL;
}//取最后一个元素
char* GetLast(GenList gl)
{GLNode *p=gl->tp;while(p->tp!=NULL)p=p->tp;//判断首元素的结点类型if(p->tag==ATOM)//原子类型则传入该原子结点地址return GetGenListStr(p,0);else   //子表类型则传入子节点的首地址return GetGenListStr(p->hp,1);}//遍历广义表
/*
void ShowGenList(GenList gl)
{//由头结点指向下一个结点(头结点不存放数据)GLNode *p = gl->tp;printf("(");//当还未遍历到最后一个结点,一直进行遍历while(p != NULL) {//对结点类型进行判断if(p->tag == ATOM){//结点类型为原子类型printf("%d",p->atom);//打印原子数据if(p->tp != NULL)//判断该结点后面是否还有结点printf(",");//有,打印","p = p->tp;//下移}else if(p->tag == CHILDLIST){//结点类型为子表ShowGenList(p->hp);//从子表的表头指针开始对子表进行遍历p = p->tp;//子表遍历完成后下移}}printf("),");//遍历结束补上括号
}*///打印广义表
void ShowGenList(GenList gl)
{//调用GetGenListStr函数将广义表转换成字符串printf("(%s)",GetGenListStr(gl,1));
}//判断广义表是否为空
bool GenListEmpty(GenList gl)
{return gl->tp==NULL; //判断表头结点尾指针的指向是否为空
}//求解广义表的长度
int  GenListLength(GenList gl)
{int length = 0;//记录长度GLNode *p = gl->tp;//从头结点的下一个结点开始统计(因为头结点不存数据)//当广义表还有元素,就继续遍历while(p != NULL){length++;//运到结点长度就加一p = p->tp;//后移}return length; //返回广义表长度
}//求解广义表的深度
int  GenListDepth(GenList gl)
{//判断广义表是否为空if(gl->tp == NULL)return 1;//空表深度为1GLNode *p = gl->tp; //指向头结点的下一个结点int maxdepth = 0; //记录深度int dep;//当广义表还未遍历完成,就一直遍历求取深度while(p != NULL){//判断结点类型是否为子表结点if(p->tag == CHILDLIST){//为子表结点//求取子表的深度dep = GenListDepth(p->hp);if(dep > maxdepth)//判断此时求得的深度是否比当前的最大深度大maxdepth =dep;//是,将dep赋给maxdepth}p = p->tp;//后移}return maxdepth+1;//返回深度(该层的深度=该层以下的最大深度+加上当前层的深度1)
}//广义表的复制:gl复制到T
void CopyGenList(GenList gl,GenList &T)
{//判断广义表是否为空if(gl == NULL){//为空return;}//如果原来的广义表T已经存放数据if(T!=NULL){DestroyGenList(T);}//创建头结点(广义表的第一个结点为头结点,其余都为尾结点)T = (GLNode*)malloc(sizeof(GLNode));assert(T != NULL);T->tag = gl->tag; //结点标记为头结点T->hp = gl->hp;T->tp = gl->tp; //把子表指针和尾指针都指向空//由头结点指向下一个结点(头结点不存放数据)GLNode *p = gl->tp; //为了不丢失gl的指向,定义一个指针来操作GLNode *q = T; //为了不丢失T的指向,定义一个指针来操作//当还未遍历到最后一个结点,一直进行遍历while(p != NULL) {//创建结点q = q->tp = (GLNode*)malloc(sizeof(GLNode));assert(q != NULL);q->tag = p->tag; //结点标记为头结点q->hp = q->tp = NULL;//将新建结点的子表指针和尾指针都赋空//对结点类型进行判断if(p->tag == ATOM){//结点类型为原子类型q->atom =p->atom;//赋值p = p->tp;//下移}else if(p->tag == CHILDLIST){//结点类型为子表CopyGenList(p->hp,q->hp);//从子表的表头指针开始对子表进行遍历p = p->tp;//子表遍历完成后下移}}
}//插入元素str( 广义表的字符表示,如:((1,2),3)  )作为广义表的第一元素
void InsertFirstGenList(GenList &gl, char *str)
{GenList t;InitGenList(t);CreateGenList(t, str);//由头结点指向下一个结点(头结点不存放数据)GLNode *p = t->tp;//往后移动,一直移动到最后一个结点while(p->tp != NULL) {p=p->tp;}//将新创建的广义表t放到gl的前面p->tp=gl->tp;//将gl的头结点连上广义表tgl->tp=t->tp;free(t);//t的头结点无用,释放
}//删除广义表第一个位置的元素
void DeleteFirstGenList(GenList &gl,char* & str)
{GenList t;InitGenList(t);t=gl->tp; //将第一个元素地址传给t//将第一个元素从广义表中断开gl->tp=gl->tp->tp;//判断要释放的结点是什么类型if(t->tag==CHILDLIST){//子表结点//保存要删除的值str=GetGenListStr(t->hp,1);//释放子表DestroyGenList(t->hp);}else if(t->tag==ATOM){//原子结点//保存值str=GetGenListStr(t,0);}free(t);
}//清空广义表
void ClearGenList(GenList &gl)
{//由头结点指向下一个结点(头结点不存放数据)GLNode *p = gl->tp;//当还未遍历到最后一个结点,一直进行遍历while(p != NULL) {//对结点类型进行判断if(p->tag == ATOM){//结点类型为原子类型gl->tp =p->tp;//将原子结点从广义表中取下free(p); //释放原子结点的内存空间p = gl->tp;//指向下一个结点}else if(p->tag == CHILDLIST){//结点类型为子表ClearGenList(p->hp);//从子表的表头指针开始对子表进行清空p = p->tp;//子表遍历完成后下移}}}//销毁广义表
void DestroyGenList(GenList &gl)
{//清空广义表ClearGenList(gl);free(gl);//释放广义表gl= NULL;
}

Main.cpp

#include"GenList.h"void main()
{GenList gl;InitGenList(gl);char *ga = "(1,2,3)";char *gb = "(1,(2,3))";char *gc = "(1,(2,3),4)";char *gd = "((1,2),3)";char *ge = "((1,2,3))";char *gf = "()";char *gg = "(1,(2,(3,(10,20),4),5),6)";char *gh = "((((1,2),1),1),6,1)";CreateGenList(gl, gg);ShowGenList(gl);printf("\n");int length = GenListLength(gl);printf("length = %d\n",length);int depth = GenListDepth(gl);printf("depth = %d\n",depth);GenList T;InitGenList(T);printf("----------------------------\n");printf("复制:");CopyGenList( gl,T);ShowGenList(T);printf("\n");printf("----------------------------\n");printf("插入前:");ShowGenList(gl);printf("\n");InsertFirstGenList(gl, ga);printf("插入后:");ShowGenList(gl);printf("\n");printf("----------------------------\n");char* str;printf("删除前:");ShowGenList(gl);printf("\n");DeleteFirstGenList(gl,str);printf("删除后:");ShowGenList(gl);printf("\n");printf("删除的首元素为:%s\n",str);printf("----------------------------\n");ShowGenList(gl);printf("\n");printf("头元素为:%s\n",GetHead(gl));printf("尾元素为:%s\n",GetTail(gl));DestroyGenList(gl);}

广义表详解(C语言版)相关推荐

  1. 数据结构殷人昆电子版百度云资源_数据结构精讲与习题详解(C语言版第2版清华大学计算机系列教材)...

    导语 内容提要 殷人昆编著的<数据结构精讲与习题详解(C语言版第2版清华大学计算机系列教材)>是清华大学出版社出版的<数据结构(C语言版)>(第2版)的配套教材,对" ...

  2. 数据结构-广义表详解(类C语言版)

    目录 广义表的概念 定义 表头 表尾 例 广义表的性质 广义表与线性表的区别 广义表的存储结构 头尾链表的存储结构 扩展线性链表的存储结构 ​ 广义表的基本运算 例 广义表的概念 定义 广义表通常记作 ...

  3. 【八大排序详解~C语言版】直接插入排序-希尔排序- 直接选择排序-堆排序-冒泡排序-快速排序-归并排序-计数排序

    八大排序 1.直接插入排序 2.希尔排序 3.直接选择排序 直接选择排序改进 4.堆排序 1.建堆 2.利用堆删除思想来进行排序 5.冒泡排序 6.快速排序 递归实现 非递归实现 7.归并排序 递归实 ...

  4. 图之邻接表详解(C语言版)

    文章目录 一.定义 二.结构 三.常用操作 四.测试 结语 附录 一.定义 图的邻接表是一种顺序与链式存储相结合的存储方式.下面给出一个示例,以便大家能够理解邻接表这种存储方式:         无向 ...

  5. 你是真的“C”——详解C语言实现文件版通讯录

    详解C语言实现文件版通讯录

  6. 教程直播第8期|一文详解 OceanBase 社区版生态工具 ODP OCP

    在 OceanBase 生态大家庭中,除了 OceanBase 数据库内核部分,还有很多功能强大的周边工具,这些工具实现了不同的功能,满足了客户多样化的需求.本文将介绍两个极具代表性的的生态工具,帮助 ...

  7. DZ各个数据表详解(DZ论坛各表详细说明,二次开发用)

    DZ各个数据表详解(DZ论坛各表详细说明,二次开发用) DZ默认库的53个数据表 cdb_access (用户权限表) uid 用户id fid 论坛id allowview 允许浏览 allowpo ...

  8. 判断数组中某个元素除自身外是否和其他数据不同_算法工程师要懂的3种算法数据结构:线性表详解...

    算法思想有很多,业界公认的常用算法思想有8种,分别是枚举.递推.递归.分治.贪心.试探法.动态迭代和模拟.当然8种只是一个大概的划分,是一个"仁者见仁.智者见智"的问题. 其实这些 ...

  9. (十二)命令模式详解(故事版)- 转

    作者:zuoxiaolong8810(左潇龙),转载请注明出处. 背景:小左是魔都某公司技术部的一名屌丝程序猿,每天的工作就是维护一个20世纪的古董级项目,由于公司不大,所以公司很多制度不太完善,导致 ...

  10. 《Linux设备驱动开发详解(第2版)》隆重出版

    Linux设备驱动开发详解(第2版)(前一版狂销3万册,畅销书最新升级) [新品] 点击看大图     基本信息 * 作者: 宋宝华       * 出版社:人民邮电出版社     * ISBN:97 ...

最新文章

  1. 基础001.Markdown编写云笔记
  2. 【译文】Web Farm和Web Garden的区别?
  3. wilkinson--生成Wilkinson特征值测试矩阵
  4. 第一章 Web MVC简介 —— 跟开涛学SpringMVC
  5. 多层 UIScrollView 嵌套滚动解决方案
  6. HTML简单注册页面
  7. 刷新页面,无论点击多少次让Element UI的Message消息提示弹出一个
  8. 当云原生遇上低代码,云端开发so easy!
  9. pythontkinter使按钮失效_python2.7为什么点击了quot;开始quot;按钮后,tkinter上的按钮,图中红色部分,再也点不动了? - SegmentFault 思否...
  10. 会议室预约微信小程序推荐_又是BYPASS!微信小程序预约 YEEZY BOOST 350 V2 只要3S就能搞定!...
  11. Maven无法加载ojdbc14.jar的解决方法
  12. MATLAB人脸识别算法
  13. 苹果4s怎么越狱_越狱源和插件大全2020.4.4
  14. 服务器上显示公式,Markdown中实时显示数学公式的方法
  15. 动态交叉表(永洪bi)
  16. 上传文件到本地操作和上传到Azure云上
  17. 小米等部分手机机型不弹出对话框问题
  18. 嵌入式蓝桥杯G431RBT6 串口配置及使用方法cube MX
  19. JavaScript—进阶篇
  20. 实例:用C#.NET手把手教你做微信公众号开发(12)--带参数二维码裂变推广

热门文章

  1. linux上删除rime方案_超强的输入法:rime的配置(linux)
  2. 浅谈stm32的低功耗模式
  3. 洛谷P1428 小鱼比可爱
  4. Git(七)——删除历史版本,保留当前状态
  5. strut2下载文件
  6. 程序员需要学数学吗?
  7. 个人博客网站编写(01)
  8. win7音量图标不见了如何解决
  9. Android系统各个版本发布时间
  10. 【图片新闻】俄罗斯水下核武器“海啸天启鱼雷”探秘