首先,按层序输入创建一棵由双亲表示法表示的树,然后把这棵树转化成用孩子兄弟表示法表示的树。
关键函数思想:
按照层序遍历每个结点,先创建一个结点,并给它赋值,读取它的双亲位置,如果它不是根节点,那么如果它的第一个孩子为空,就将它作为第一个孩子,否则寻找孩子链表的末端,依次作为兄弟存入。
代码:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 100
typedef struct CSTNode {
int data;
struct CSTNode* firstChild, * nextSibling;
} CSTNode, * CSTree;
typedef struct {
int data;
int parent; //双亲位置域
}PTNode;
typedef struct {
PTNode node[MAXSIZE];
int n; //结点数
}PTree;
//由双亲结构创建树的孩子兄弟链表
CSTree CreateCSTreeByParent(PTree T)
{
int i, j, k;
CSTree p, q;
CSTree tmp[MAXSIZE];
//双亲表按层序存储
for (i = 0, j = 0; i < T.n; i++)
{
k = T.node[i].parent;
p = (CSTree)malloc(sizeof(CSTNode));
if (!p)
exit(OVERFLOW);
p->data = T.node[i].data;
p->firstChild = p->nextSibling = NULL;
if (k != -1)
{
if (tmp[k]->firstChild == NULL) //作为第一个孩子
tmp[k]->firstChild = p;
else
{
q = tmp[k]->firstChild; //寻找孩子链表的末端
while (q->nextSibling)
q = q->nextSibling;
q->nextSibling = p;
}//else
}//if
tmp[j++] = p;
}//for
if (j)
return tmp[0];
else
return NULL;
}
void TreePrintEdge(CSTree T)
{
CSTNode* p;
for (p = T->firstChild; p; p = p->nextSibling)
{
printf("(%d,%d) ", T->data, p->data); //输出T的孩子
TreePrintEdge(p); //输出p的孩子
}
}
int main()
{
PTree PT;
CSTree CST;
printf("请输入树的结点数\n");
scanf("%d", &PT.n);
printf("请按层序输入结点的值和双亲位置\n");
for (int i = 0; i < PT.n; i++)
scanf("%d%d", &PT.node[i].data, &PT.node[i].parent);
CST = CreateCSTreeByParent(PT);
printf("创建的孩子兄弟表示法二叉树为\n");
TreePrintEdge(CST);
printf("\n");
return 0;
}
下面是测试样例: