根据广义表构造二叉树 c语言,[树] △ 6.75|6.76 由广义表构造树(孩子链表CTree)并以广义表的形式输出...

#include

#include

#include

#ifndef BASE

#define BASE

#define TRUE 1

#define FALSE 0

#define OK 1

#define ERROR 0

#define INFEASIBLE -1

#define OVERFLOW -2

typedef int Status;

typedef int bool;

#endif

#define TElemType char

void visit(TElemType e) {

printf("%c", e);

}

#define MAX_TREE_SIZE 100

#define maxSize 50

typedef struct CNode{

int index; //这个孩子的结点号(注意:在严书中变量名为child)

struct CNode *next; //下一个孩子结点

}CNode, *ChildPtr; //孩子结点结构(在严书中名为CTNode)

typedef struct{

TElemType data;

CNode* firstchild;

}PNode; //双亲结点结构(在严书中,结构名为CTBox)

typedef struct{

PNode nodes[MAX_TREE_SIZE];

int n,r; //结点数 和 根结点的位置

}CTree; //树结构

// 先根遍历

void SubPreOrder(CTree T, int index) {

CNode *child;

visit(T.nodes[index].data);

for (child=T.nodes[index].firstchild; child; child=child->next)

SubPreOrder(T, child->index);

}

void PreOrder(CTree T) {

SubPreOrder(T, T.r);

}

/*-------------------------

|6.63 求树的深度 |

-------------------------*/

int SubTreeDepth(CTree T, int index) { //序号为index的子树深度

int max=-1; //孩子的最大深度

int sd; //孩子的深度

CNode *p;

if (!T.nodes[index].firstchild) return 1; //没有孩子,深度为1

for (p=T.nodes[index].firstchild; p; p=p->next) { //遍历该结点的所有孩子

sd = SubTreeDepth(T, p->index); //求孩子的深度

if (max

}

return max+1; //孩子的最大深度+1

}

int TreeDepth(CTree T) {

return SubTreeDepth(T, T.r);

}

/*-------------------------

|6.72 将树打印成树状 |

-------------------------*/

void PrintAsTree(CTree T, int index, int i) {

/*思路

1. 观察题目输出的序列ABEFCGD

2. 此为树的先根遍历–>对应为二叉树存储的先序遍历

3. 前面的空格是该结点所在的层数

*/

CNode *p;

int cnt;

//输出空格

for (cnt=1; cnt

//输出元素

visit(T.nodes[index].data);printf("\n");

//遍历它的孩子

for(p=T.nodes[index].firstchild; p; p=p->next)

PrintAsTree(T, p->index, i+1);

}

// 树的层序次序+每个结点的度 --> 创建CTree

Status CreateCTreeByLevelDegree(CTree *pT,char *levelstr, int *degree) {

CNode *c,*sibling;

int parent;

int i,cnt;

//创建结点

for (i=0; i

//赋值

pT->nodes[i].data = levelstr[i];

pT->nodes[i].firstchild = NULL;

}

pT->n=strlen(levelstr); //个数

pT->r=0; //根结点

//为孩子找爸爸

parent=0; //当前的爸爸

i=1; //遍历孩子

cnt=0; //已经为parent找到了cnt个孩子

while (i

if (degree[parent]==0 || cnt==degree[parent]) { //parent没有孩子 || parent的孩子已经全部找到

cnt=0;

parent++;

continue;

}

cnt++; //为parent找到了一个孩子

//创建孩子结点

c = (CNode *)malloc(sizeof(CNode)); if (!c) exit(OVERFLOW);

c->index = i; //孩子的编号

c->next = NULL;

if (cnt==1) { //第一个孩子

pT->nodes[parent].firstchild = c;

} else { //不是第一个孩子

for(sibling=pT->nodes[parent].firstchild; sibling->next; sibling=sibling->next) ;

sibling->next = c;

}

i++;

}

return TRUE;

}

/*-------------------------

|6.75 用广义表构造树 |

-------------------------*/

// @Quesion:有一些格式检测不了"A(" "A()" "A)("

Status CreateCTreeByGList(CTree *pT, int parent) {

// 创建新结点newNode --> 放在下标为pT->n

// 该结点的爸爸为parent

char c;

CNode *p, *q;

int newNode;

//创建newNode结点

newNode = pT->n; //新结点的下标

for (c=getchar(); c!='\n'; c=getchar() ) {

if (c>='A' && c<='Z') { // 结点信息

pT->nodes[newNode].data = c; //给结点赋值

pT->nodes[newNode].firstchild = NULL; //给结点赋值

pT->n++; //结点数+1

//newNode有爸爸,即parent

if (parent!=-1) {

//创建孩子结点

p = (CNode *)malloc(sizeof(CNode));if (!p) exit(OVERFLOW);

p->index = newNode;

p->next = NULL;

//儿子父亲相认

if (pT->nodes[parent].firstchild==NULL) {

pT->nodes[parent].firstchild = p;

} else {

for (q=pT->nodes[parent].firstchild; q->next; q=q->next) ;

q->next = p;

}

}

} else if (c=='(') { //是newNode的孩子

CreateCTreeByGList(pT, newNode); //开始创建newNode的孩子

} else if (c==',') { //是newNode的兄弟,即parent的下一个孩子

CreateCTreeByGList(pT, parent); //parent的下一个孩子

return OK; //newNode结点构造完成(自己创建了、孩子创建了、兄弟创建了)

} else if (c==')') { //parent构造完毕

return OK;

} else {

return ERROR; //格式错误

}

}

return OK;

}

/*-------------------------

|6.76 以广义表的形式输出 |

-------------------------*/

Status PrintAsGList(CTree T,int parent) {

CNode *p;

if (T.n<=0) return ERROR;

visit(T.nodes[parent].data);

if (T.nodes[parent].firstchild) {

printf("(");

for (p=T.nodes[parent].firstchild; p; p=p->next) {

PrintAsGList(T, p->index);

if (p->next) printf(",");

}

printf(")");

}

return OK;

}

int main() {

/*6.75测试数据

A(B(E,F),C(G),D)

A

A(B)

A(B,C)

A(B,C(D,E))

*/

CTree T;

T.n=0;T.r=0;

CreateCTreeByGList(&T, -1); //6.75

PrintAsGList(T, T.r); //6.76

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值