树的表示法
-
图像的表示法
双亲表示法:数据 双亲
孩子表示法:数据 孩子
孩子兄弟表示法:长子 数据 兄弟
-
括号表示法
-
遍历表示法
前序遍历
中序遍历
后序遍历
层序遍历
双亲表示法
孩子表示法
孩子兄弟表示法
-
结构示意图
将父子结点转为兄弟结点
进一步操作,将B、C、D的父子节点变换为兄弟结点
-
树结点
typedef struct CSNode{ Element data; //结点数据域 struct CSNode * friendChild; //长子 struct CSNode * nextSibling; //兄弟 }CSNode, * CSTree;
优点:
他和二叉树的二叉链表表示完全一样,便于将一般的树结构转为二叉树进行处理
树和二叉树的相互转换 - 孩子兄弟表示法
左图是原树;右图是转化之后的树
孩子兄弟表示法基本操作
#define NAME_SIZE 255
/** 数据元素 */
typedef struct
{
int id;
char name[NAME_SIZE];
}ElementType;
/** 孩子兄弟结点 */
typedef struct cbNode{
ElementType data; //数据域
struct cbNode * firstChild; //长子结点
struct cbNode * nextSibling; //兄弟结点
}CBNode, * CBTree; // *CBTree 二级指针
/** 初始化空树 */
void InitCBTree(CBTree * tree)
{
*tree = (CBTree)malloc(sizeof(CBNode));
(*tree)->firstChild = NULL;
(*tree)->nextSibling = NULL;
}
/** 构造树 */
static int id = 0;
void CreateCBTree(CBNode ** node)
{
char inputName[255];
gets(inputName);
//判断用户输入的是否是回车键
if(strcmp(inputName, "\0") == 0) return;
if(*node == NULL)
{
*node = (CBNode *)malloc(sizeof(CBNode));
(*node)->firstChild = NULL;
(*node)->nextSibling = NULL;
}
//为结点赋值
(*node)->data.id = ++id;
strcpy((*node)->data.name, inputName);
//分别遍历输入长子结点和兄弟结点
printf("请输入长子结点:");
CreateCBTree(&((*node)->firstChild));
printf("请输入兄弟结点:");
CreateCBTree(&((*node)->nextSibling));
}
/** 先序遍历 */
void PreOrderCBTree(CBNode * node)
{
if(node != NULL)
{
printf("[%d, %s] ", node->data.id, node->data.name);
CBNode * p = node->firstChild;
PreOrderCBTree(p); //访问长子结点
while(p)
{
p = p->nextSibling; //访问兄弟结点
PreOrderCBTree(p);
}
}
}