广义表的定义
广义表是线性表的推广,又将其称为列表(lists,用复数形式表示与一般表list区别),它是广泛应用于人工智能等领域的表处理语言。说白了:线性表是由n个数据元素组成的有限序列。其中每个组成元素被限定为单个元素,有时这种限制需要扩展,这种扩展了的线性表就是广义表。
一般表现形式为:ls=(a1,a2,…,ai,…an),,其中的ai可以是一个元素称之为广义表ls的原子,也可以是一个广义表称为广义表的子表。
广义表的性质
1、广义表是一种多层次的数据结构,广义表的元素可以是原子,也可以是子表,而子表的元素还可以是子表。
2、广义表可以是递归的表,广义表的定义并没有限制元素的递归,即广义表也可以是其自身的子表。
3、广义表可以为其他表所共享,即可以以子表的形式存在于其他广义表中。
广义表可以看作是线性表的推广,线性表是广义表的特例。广义表的结构相当灵活,在某种前提下,它可以兼容线性表、数组、树和有向图的各种常用的数据结构。
二叉树的定义
二叉树是非线性的,每个节点最多可有两个后继。二叉树的存储结构有两种,顺序存储结构和链式存储结构
顺序存储结构
二叉树的顺序存储结构就是用一维数组存储二叉树的节点,并且节点存储位置即数组的下标要能体现节点之间的逻辑关系,比如双亲与孩子的关系,左右兄弟的关系等。否则二叉树上的基本操作在顺序存储结构上难以实现。故依据二叉树的性质,完全二叉树和满二叉树采用顺序存储结构比较合适
二叉树链式存储结构
为了节约空间,自然而然的想到了链式存储结构。
1、二叉链表存储
二叉链表中,每个节点由三个域组成,除了用来存放二叉树结点数据信息的数据域外,还有两个指针域,左指针域指向该节点左孩子的指针,右指针域指向该节点右孩子的指针。当左右孩子不存在时,用空表示。(符号^或者NULL)
节点存储结构
typedef struct node
{
int data;
struct node*lchild;
struct node*rchild;
}bitnode,*binode;
2、三叉链表存储
在二叉链表中查找某一节点的孩子节点是很方便的但要查找该节点的双亲节点则十分的困难。为了便于找到双亲节点,可以在二叉链表的基础上增加一个parent域。
用以指向该节点的双亲节点。
三叉链表节点的存储结构
typedef struct node
{
int data;
struct node*lchild;
struct node*parent;
struct node*rchild;
}snode,*btree;
然而,用三叉链表易于找到节点的左右孩子节点,又容易找到其双亲节点。尽管在二叉链表中无法由节点直接找到其双亲,但由于二叉链表结构灵活,操作方便,故二叉链表是最常用的二叉树存储结构。
用二叉链表表示二叉树,建立一颗二叉树,采用广义表表示方法
代码
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
char data;
struct node*lchild;
struct node*rchild;
}bitnode;
bitnode*creat()
{
bitnode*t;
char ch;
ch=getchar();
if(ch=='0')
t=NULL;
else
{
t=(bitnode*)malloc(sizeof(bitnode));
t->data=ch;
t->lchild=creat();
t->rchild=creat();
}
return t;
}
void printbitree(bitnode*t)
{
if(t!=NULL);
{
printf("%c",t->data);
if(t->lchild!=NULL||t->rchild!=NULL)
{
printf("(");
printbitree(t->lchild);
if(t->rchild!=NULL)
printf(",");
printbitree(t->rchild);
printf(")");
}
}
}
int main()
{
bitnode*t=NULL;
printf("input pretree,the 0 is null:\n");
t=creat();
printf("the general tree:\n");
printbitree(t);
putchar('\n');
free(t);
return 0;
}
总结
本次采用的是递归建树,但是递归有个坏处,那就是太过于耗损时间和空间了,如果不是因为简单,一般都不采用递归法。