广义表的创建与打印

广义表的创建与打印

    

      本文取自《数据结构与算法》(C语言版)(第三版),出版社是清华大学出版社。

本博文作为学习资料整理。

源码是VC++ 6.0上可运行程序,我挪到了VS2010中运行。

在VS2010中新建C++ Win32 控制台应用程序项目,创建结果截图:

     

     1.广义表的创建:

广义表的存储结构示意图:演示样例:C(x, y, (a, b))

广义表能够通过以下的递归方式进行定义。

基本项:(1)广义表为空表,当s为空时;(2)广义表为原子结点。当s为单字符串时。

归纳项:如果Subs为S去掉最外层括号对的串,记作“S1。S2。...,Sn”。当中Si(i=1,...,n)为非空字符串。对每一个Si建立表结点,并令其hp域的指针为由Si建立的子表的头指针,除最后建立的表结点的尾指针为NULL外,其余表结点的尾指针均指向在它之后建立的表结点。也就是说,由于Si是一个字符串,首先要为这个字符串建立一个表结点,表结点的指针域指向Si中的元素。它的tp域指向下一次建立的Si+1,而Sn的tp域为空。

由于在广义表的定义中要用到subs串,因此须要一个函数来求这个串。这里採用函数Getsubs(str,hstr)来实现。

当中,hstr存放的是str中第1个","之前的子串,而且函数将str改动为删除子串hstr和","之后的剩余串。

若串str中没有",",则hstr即为str。而str改动为空串NULL。

2.广义表的打印:

打印广义表的算法思想是:先打印一个左括号"(",若遇到tag=ATOM,则打印该结点的值。假设此结点后面有后继结点,则再打印一个",";假设tag=LIST,说明是一个子表,则递归调用函数,打印这个子表。打印全然部结点以后,最后打印一个“)”。

源程序例如以下:GeneralList.cpp

// GeneralList.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef enum {ATOM, LIST}ElemTag;    //ATOM==0 原子, LIST==1 子表

struct GLNode
{
	ElemTag tag;        //标识域
	union
	{
		char atom;
		struct GLNode *hp;
	};
	struct GLNode *tp;
};

typedef struct GLNode GList;

//求取广义表的子串Subs
void Getsubs(char str[], char hstr[])
{
	int i=0;
	int j=0;
	int k=0;     //用来记录没有匹配的左括号数
	int r=0;
	char s[100];
	while(str[i]&&(str[i]!=','||k))
	{
		if(str[i]=='(')
			k++;
		else if(str[i]==')')
			k--;

		if(str[i]!=','||str[i]==','&&k)
		{
			hstr[j]=str[i];
			i++;
			j++;
		}
	}
	hstr[j]='\0';
	if(str[i]==',')
		i++;
	while(str[i])
	{
		s[r]=str[i];
		r++;
		i++;
	}
	s[r]='\0';
	strcpy(str,s);

}

//创建广义表
GList *GListCreate(char str[])
{
  GList *G;
  char subs[100];
  char hstr[100];
  GList *q;
  int len=strlen(str);
  if(len==0||!strcmp(str,"()"))
	  G=NULL;
  else if(len==1)  //原子结点的情况
  {
		  G=(GList *)malloc(sizeof(GList));
		  if(!G)
		  {
			  printf("申请空间失败!");
			  exit(0);
		  }
		  G->tag = ATOM;
		  G->atom = *str;
		  G->tp = NULL;
  }
  else
  {
	 GList *p;
     G=(GList *)malloc(sizeof(GList));
	 if(!G)
	 {
		printf("申请空间失败!

");
		exit(0);
	  }
	  G->tag = LIST;
	  p=G;
	  str++;
	  strncpy(subs,str,len-2);       //去掉最外面的()
	  subs[len-2]='\0';
	  while(len>0)
	 {
		GList *r;
		Getsubs(subs,hstr);         //将subs分开为表头hstr和表尾subs
		r=GListCreate(hstr);        //生成表头的广义表
		p->hp=r;
		q=p;
		len=strlen(subs);
		if(len>0)
		{
           p=(GList *)malloc(sizeof(GList));
		   if(!G)
		   {
			  printf("申请空间失败!");
			  exit(0);
		    }
		    p->tag = LIST;
			q->tp=p;
		 }
	}
	q->tp=NULL;
  }
  return G;
}

//打印广义表
void GListPrint(GList *G)
{
   GList *q,*p;
   printf("(");
   while(G)
   {
	   p=G->hp;
	   q=G->tp;
	   if(p&&q&&!p->tag)       //p为原子结点,而且有兴许结点
	   {
         printf("%c,",p->atom);
		 p=q->hp;
	     q=q->tp;
	   }
	   if(p&&!p->tag)           //p为原子结点,而且没有兴许结点
	   {
         printf("%c",p->atom);
		 break;
	   }
	   else
	   {
		   if(!p)
              printf("()");          //p为空表
		   else
			  GListPrint(p);
		   if(q)
              printf(",");          //还存在着兴许的结点
		   G=q;
	   }
   }
   printf(")");
}

int main()
{
	int n;
	char *s;
	GList *G;
	printf("请输入广义表的字符数:\n");
	scanf("%d",&n);
    printf("请输入广义表:\n");
	s=(char *)malloc(n*sizeof(char));
	scanf("%s",s);
	G=GListCreate(s);
    printf("所输入的广义表为:\n");
	GListPrint(G);
	printf("\n");
	return 0;
}

Ctrl+F5执行GeneralList.cpp的执行结果:例如以下截图:

时间: 2024-08-09 18:20:57

广义表的创建与打印的相关文章

数据结构复习之广义表的创建和遍历

#include<iostream> #include<string> #include<cstring> #include<cstdlib> #include<list> #include<map> using namespace std; class GLNode{ public: int tag; string node; class { public: GLNode *hp, *tp; } ptr; }; typedef GL

广义表

其中包括广义表的创建.输出.拷贝构造.赋值运算符重载.析构.有效数据个数以及广义表深度 #pragma once #include<iostream> #include<assert.h> #include<ctype.h> using namespace std; enum Type {  HEAD, VALUE, SUB };//头结点.值.子表 struct GeneralizedNode {  Type _type;  //广义表结点类型  Generalize

【代码】C++实现广义表及其测试用例

广义表是我第一次用递归接触链式的数据结构,其结构如下: HEAD->VAL->VAL->LINK(->HEAD.....)->VAL->......     在这里,我们的头结点与link节点是不存储数据的,由此我们便可以定义出节点的数据结构: typedef int DataType; enum NodeType//枚举类型定义节点类型 { HEAD, VALUE, SUB, }; struct GeneralizedNode { public: Generalize

数据结构-顺序树的创建以及按广义表输出

1 #include"stdio.h" 2 #define MaxSize 30 3 typedef char DataType; 4 typedef struct TreeNode{ 5 DataType data[MaxSize]; 6 int count; 7 }BinTree; 8 int k = 0; 9 //初始化树 10 void initBinTree(BinTree *t) 11 { 12 for( int i= 0; i< MaxSize; i++) 13 {

二叉树的广义表创建及中序遍历、后序遍历、层次遍历的非递归算法(C语言)

广义表创建二叉树关于用广义表的形式表示二叉树的形式如下 ①广义表中的一个字母代表一个结点的数据信息.②每个根结点作为由子树构成的表的名字放在义表的前面.③每个结点的左子树与右子树之间用逗号分开.若结点只有右子树面无左子树,则该逗号不能省略.④在整个广义表的末尾加一个特殊符号(如“@”)作为结束标志. 下面先用自然语言描述算法如下.依次从广义表中取得-个元素,并对取得的元素做如下相应的处理. ①若当前取得的元素为字母,则按如下规则建立一个新的(链)结点.a)若该结点为二叉树的根结点,则将该结点的地

【数据结构】广义表的默认成员函数、深度、大小、打印

广义表的定义: 广义表是非线性的结构,是n个元素的有限序列. 举例:A=(a,b,(c,d)) 我们先定义它的结构: (1)它有三种节点,头节点.值节点.子表节点. (2)两种指向下一节点的指针:指向下一值值节点的指针_next,指向子表节点的指针_sublink. (3)_next与_sublink只有一种 enum Type//用枚举形式来定义广义表中三种节点类型 {     HEAD, //头类型     VALUE,//值类型     SUB,//子表类型 }; struct Gener

33. 蛤蟆的数据结构笔记之三十三广义表实现二

33. 蛤蟆的数据结构笔记之三十三广义表实现二 本篇名言:" 希望是附丽于存在的,有存在,便有希望,有希望,便是光明.--鲁迅" 我们继续来看下广义表的其他代码实现.代码均来自网络,解释来自蛤蟆,均亲测可行. 欢迎转载,转载请标明出处: 1.  广义表实现二 1.1         main 创建两个链表的指针head和L. 输入一个字符串,调用GLCreate函数创建广义表.显示,获取头表,尾表,输出长度,深度,原子个数,复制列表,Merge列表,遍历,比较广义表操作. 如下图1:

数据结构之---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:原

c++实现广义表

广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列. 广义表的定义是递归的,因为在表的描述中又得到了表,允许表中有表. <1> A = () <2> B = (a,b) <3> C = (a,b,(c,d)) <4> D = (a,b,(c,d),(e,(f),h)) <5> E = (((),())) 如下图所示: 广义表主要使用递归实现,表与表之间使用链式结构来存储.下面就来看看代码怎样实现的: #pragma once #i