您的位置:首页 > 其它

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

2015-02-25 01:25 585 查看
树的存储结构

/*树的存储结构*/

/*双亲表示法*/
#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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
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).中序遍历森林中剩余的树.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐