transform方法流程:
1、构造两个队列,普通树队列和二叉树队列。
2、将二叉树的根入队列,构造普通树的根顶点并入对应队列。
3、循环判断二叉树队列不为空。
4、从两个队列中分别取出一个元素,分别为bnode,node。
5、当bnode没有左孩子时,不考虑这种情况。因为此时的node没有孩子。
6、当bnode有左孩子时,构造普通树节点,数据为左孩子的数据。将该普通节点和左孩子分别入对应队列。同时让node的第一个孩子指针指向该树节点。(对同一个点而言二叉树的左孩子为树的第一个孩子)
7、从这个普通节点开始,一直寻找它的右孩子。每找到一个,对应构造一个二叉树节点。并将这些节点依次赋给node的孩子指针。同时将这些构造节点和二叉树的右孩子节点入队列。
#include <>
#include <>
#define N 3 //定义每个节点的最大孩子数
#define M 9 //定义树中节点的个数
struct TreeNode
{
char data;
struct TreeNode *childs[N];
};
typedef struct TreeNode TreeNode; //定义类型
struct BTreeNode
{
char data;
struct BTreeNode *lchild, *rchild;
};
typedef struct BTreeNode BTreeNode;
/*------------------普通树的队列开始--------------------*/
struct QueueTree
{
int i, j;
TreeNode **queue;
};
typedef struct QueueTree QueueTree;
QueueTree * initQueueTree()
{
//分配一个队列空间
QueueTree *tree = (QueueTree *)malloc(sizeof(QueueTree));
//分配M个树节点指针空间
tree->queue = (TreeNode **)malloc(sizeof(TreeNode *)*M);
tree->i = 0;
tree->j = 0;
return tree;
};
void freeQueueTree(QueueTree *tree) //释放分配空间
{
free(tree->queue);
free(tree);
}
void addQueueTree(QueueTree *tree, TreeNode *node) //加入队列
{
if(tree->j == M) //队列已满
return;
tree->queue[tree->j] = node;
tree->j++;
}
TreeNode * delQueueTree(QueueTree *tree)
{
if(tree->i == tree->j) //队列已空
return NULL;
TreeNode *node = tree->queue[tree->i];
tree->i++;
return node;
}
int emptyQueueTree(QueueTree *tree)
{
return tree->i==tree->j; //1空
}
/*--------------------普通树的队列结束----------------------*/
/*--------------------二叉树的队列开始----------------------*/
struct QueueBTree
{
int i, j;
BTreeNode **queue;
};
typedef struct QueueBTree QueueBTree;
QueueBTree * initQueueBTree()
{
//分配一个队列空间
QueueBTree *btree = (QueueBTree *)malloc(sizeof(QueueBTree));
//分配M个树节点指针空间
btree->queue = (BTreeNode **)malloc(sizeof(BTreeNode *)*M);
btree->i = 0;
btree->j = 0;
return btree;
}
void freeQueueBTree(QueueBTree *btree) //释放分配空间
{
free(btree->queue);
free(btree);
}
void addQueueBTree(QueueBTree *btree, BTreeNode *node) //加入队列
{
if(btree->j == M) //队列已满
return;
btree->queue[btree->j] = node;
btree->j++;
}
BTreeNode * delQueueBTree(QueueBTree *tree)
{
if(tree->i == tree->j) //队列已空
return NULL;
BTreeNode *node = tree->queue[tree->i];
tree->i++;
return node;
}
int emptyQueueBTree(QueueBTree *tree)
{
return tree->i==tree->j; //1空
}
/*--------------------二叉树的队列结束----------------------*/
上面定义的是需要用到的队列以及一些方法。转化方法如下:
TreeNode * transform(BTreeNode *broot)
{
int i, j;
TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode));
root->data = broot->data;
for(i=0; i<N; i++)
root->childs[i] = NULL;
QueueTree *queue = initQueueTree();
addQueueTree(queue, root);
QueueBTree *bqueue = initQueueBTree();
addQueueBTree(bqueue, broot);
while(emptyQueueBTree(bqueue) == 0)
{
BTreeNode *bnode = delQueueBTree(bqueue);
TreeNode *node = delQueueTree(queue);
if(bnode->lchild != NULL)
{
TreeNode *t0 = (TreeNode *)malloc(sizeof(TreeNode));
t0->data = bnode->lchild->data;
for(i=0; i<N; i++)
t0->childs[i] = NULL;
node->childs[0] = t0;
j = 1;
BTreeNode *p = bnode->lchild;
addQueueBTree(bqueue, p);
addQueueTree(queue, t0);
while(p->rchild != NULL)
{
p = p->rchild;
TreeNode *tj = (TreeNode *)malloc(sizeof(TreeNode));
tj->data = p->data;
for(i=0; i<N; i++)
tj->childs[i] = NULL;
node->childs[j++] = tj;
addQueueBTree(bqueue, p);
addQueueTree(queue, tj);
}
}
}
return root;
}
代码运行还需要完成以下功能。构造二叉树,二叉树遍历,普通树遍历,main方法,树空间释放。
/*二叉树的构造开始*/
BTreeNode * initTree()
{
BTreeNode *root = (BTreeNode *)malloc(sizeof(BTreeNode));
root->data = 'a';
BTreeNode *p1 = (BTreeNode *)malloc(sizeof(BTreeNode));
p1->data = 'b';
BTreeNode *p2 = (BTreeNode *)malloc(sizeof(BTreeNode));
p2->data = 'c';
BTreeNode *p3 = (BTreeNode *)malloc(sizeof(BTreeNode));
p3->data = 'd';
BTreeNode *p4 = (BTreeNode *)malloc(sizeof(BTreeNode));
p4->data = 'e';
BTreeNode *p5 = (BTreeNode *)malloc(sizeof(BTreeNode));
p5->data = 'f';
BTreeNode *p6 = (BTreeNode *)malloc(sizeof(BTreeNode));
p6->data = 'g';
BTreeNode *p7 = (BTreeNode *)malloc(sizeof(BTreeNode));
p7->data = 'h';
BTreeNode *p8 = (BTreeNode *)malloc(sizeof(BTreeNode));
p8->data = 'i';
root->lchild = p1;
root->rchild = NULL;
p1->lchild = p4;
p1->rchild = p2;
p2->lchild = NULL;
p2->rchild = p3;
p3->lchild = p7;
p3->rchild = NULL;
p4->lchild = NULL;
p4->rchild = p5;
p5->lchild = NULL;
p5->rchild = p6;
p6->lchild = NULL;
p6->rchild = NULL;
p7->lchild = NULL;
p7->rchild = p8;
p8->lchild = NULL;
p8->rchild = NULL;
return root;
}
void destroyTree(TreeNode *root) //树空间释放
{
if(root == NULL)
return;
if(root->childs[0] == NULL && root->childs[1] == NULL && root->childs[2] == NULL)
free(root);
else
{
if(root->childs[0] != NULL)
destroyTree(root->childs[0]);
if(root->childs[1] != NULL)
destroyTree(root->childs[1]);
if(root->childs[2] != NULL)
destroyTree(root->childs[2]);
}
}
void iterator(TreeNode *root) //树层序遍历
{
if(root == NULL)
return;
QueueTree *queue = initQueueTree();
addQueueTree(queue, root);
while(emptyQueueTree(queue) == 0)
{
TreeNode *p = delQueueTree(queue);
printf("%c ", p->data);
int i;
for(i=0; i<N; i++)
{
if(p->childs[i] != NULL)
{
addQueueTree(queue, p->childs[i]);
}
}
}
freeQueueTree(queue);
}
void preOrder(BTreeNode *root) //二叉树前序遍历
{
if(root == NULL)
return;
printf("%c ", root->data);
preOrder(root->lchild);
preOrder(root->rchild);
}
void destroyBTree(BTreeNode *root) //二叉树空间释放
{
if(root == NULL)
return;
if(root->lchild == NULL && root->rchild == NULL)
free(root);
else
{
if(root->lchild != NULL)
destroyBTree(root->lchild);
if(root->rchild != NULL)
destroyBTree(root->rchild);
}
}
int main()
{
BTreeNode *root = initTree();
preOrder(root); //前序输出二叉树
printf("\n");
TreeNode *broot = transform(root);
iterator(broot); //层序输出普通树
destroyBTree(root);
destroyTree(broot);
return 0;
}