c语言孩子兄弟法存储一棵树,树、森林与二叉树(树的存储结构(树的孩子兄弟链表应用举例),树转换为二叉树,二叉树转换成树和森林,树和森林的遍历)...

树的存储结构

/*树的存储结构*/

/*双亲表示法*/

#define MAXSIZE 200

typedef char ElemType;

typedef struct PNode//双亲表示法的结点定义

{

ElemType data;

int parent;//指示结点的双亲

}PNode;

typedef struct//双亲表示法的类型定义

{

PNode node[MAXSIZE];

int num;//结点的个数

}PTree;

/*孩子表示法*/

#define MAXSIZE 200

typedef char ElemType;

typedef struct CNode//孩子表示法的结点定义

{

int child;

struct CNode *next;//指向下一个结点

}ChildNode;

typedef struct//n个结点数据与孩子链表指针构成一个结构

{

ElemType data;

ChildNode *firstchild;//孩子链表的指针

}DataNode;

typedef struct//孩子表示法类型定义

{

DataNode node[MAXSIZE];

int num,root;//结点的个数,根结点在顺序表中的位置

}CTree;

/*孩子兄弟表示法*/

typedef char ElemType;

typedef struct CSNode//孩子兄弟表示法类型定义

{

ElemType data;

struct CSNode *firstchild,*nextsibling;//指向第一个孩子和下一个兄弟

}CSNode,*CSTree;

树的孩子兄弟链表应用举例

头文件:函数的声明

#include

#include

#include

#include

typedef int ElemType;

typedef struct CSNode//孩子兄弟表示法类型定义

{

ElemType data;

struct CSNode *firstchild,*nextsibling;//指向第一个孩子和下一个兄弟

}CSNode,*CSTree;

void InitCSTree(CSTree *T);//树的初始化

void DestroyCSTree(CSTree *T);//树的摧毁操作

void CreateCSTree(CSTree *T,ElemType *e,int *index);//创建树操作

int DepCSTree(CSTree T);//求树的深度

void PreTraverseCSTree(CSTree T,void(*visit)(ElemType *e));//树的先根遍历

void PostTraverseCSTree(CSTree T,void(*visit)(ElemType *e));//树的后根遍历

void DisplayCSTree(ElemType *e);//输出树的结点

函数的定义

#include "树.h"

void InitCSTree(CSTree *T)//树的初始化

{

*T = 0;

}

void DestroyCSTree(CSTree *T)//树的摧毁操作

{

CSTree p = *T;

if(p)

{

DestroyCSTree(&(p->firstchild));

DestroyCSTree(&(p->nextsibling));

free(p);

*T = 0;

}

}

void CreateCSTree(CSTree *T,ElemType *e,int *index)//创建树操作

{

if(e[*index] == 0)

{

*T = 0;

(*index)++;

}

else

{

*T = (CSTree)malloc(sizeof(CSNode));

(*T)->data = e[*index];

(*index)++;

CreateCSTree(&((*T)->firstchild),e,index);

CreateCSTree(&((*T)->nextsibling ),e,index);

return;

}

}

int DepCSTree(CSTree T)//求树的深度

{

CSTree p;

int k,d = 0;

if(T == NULL)

{

return 0;

}

p = T->firstchild ;

while(p != NULL)

{

k = DepCSTree(p);

if(d < k)

{

d = k;

}

p = p->nextsibling ;

}

return d+1;

}

void PreTraverseCSTree(CSTree T,void(*visit)(ElemType *e))//树的先根遍历

{

if(T)

{

(*visit)(&T->data);

PreTraverseCSTree(T->firstchild ,visit);

PreTraverseCSTree(T->nextsibling ,visit);

}

}

void PostTraverseCSTree(CSTree T,void(*visit)(ElemType *e))//树的后根遍历

{

if(T)

{

PostTraverseCSTree(T->firstchild ,visit);

(*visit)(&T->data);

PostTraverseCSTree(T->nextsibling ,visit);

}

}

void DisplayCSTree(ElemType *e)//输出树的结点

{

printf("%2c",*e);

}

函数的应用

#include "树.h"

int main(void)

{

int text[] = {'A','B','E',0,'F','H',0,'I',0,'J',0,0,0,'C',0,'D','G',0,0,0,0};

int h = 0;

CSTree T;

InitCSTree(&T);

CreateCSTree(&T,text,&h);

printf("树的先根遍历结果是:\n");

PreTraverseCSTree(T,DisplayCSTree);

printf("\n");

printf("树的后根遍历结果是:\n");

PostTraverseCSTree(T,DisplayCSTree);

printf("\n");

printf("树的深度是:%2d",DepCSTree(T));

printf("\n");

DestroyCSTree(&T);

return 0;

}

树转化成二叉树:

1.在树中兄弟结点之间加一条连线;

2.在树中,只保留双亲结点与第一个孩子结点之间的连线,将双亲结点与其他孩子结点的连线删除;

3.将树中的各个分支,以某个结点为中心进行旋转,子树以根结点成对称形状.

森林转换为二叉树:

1.把森林中的所有树都转换为对应的二叉树;

2.从第二棵树开始,将转换后的二叉树作为前一颗树根结点的右孩子,插入到前一棵树中.然后将转换后的二叉树进行相应的旋转.

二叉树转换成树和森林:

1.在二叉树中,将某节点的所有右孩子结点、右孩子的右孩子结点……都与该结点的双亲结点用线条连接;

2.删除掉二叉树中双亲结点与右孩子结点的原来的连线;

3.调整转换后的树或森林,将结点的所有孩子结点处于同一层次.

树的遍历

1.先根遍历

(1).访问根结点;

(2).按照从左到右的顺序依次先根遍历每一棵子树.

2.后根遍历

(1)..按照从左到右的顺序依次后根遍历每一棵子树;

(2).访问根结点.

森林的遍历

1先序遍历

(1).访问森林中第一棵树的根结点;

(2).先序遍历第一棵树的根结点的子树;

(3).先序遍历森林中剩余的树.

2.

(1).中序遍历第一棵树的根结点的子树;

(2).访问森林中第一棵树的根结点;

(3).中序遍历森林中剩余的树.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值