输出树的各条边
普通树
树采用孩子兄弟方式存放,结点结构为:
其中fch表示表示指向第一个孩子,nsib表示指向下一个兄弟。编写算法,要求由根结点开始逐层输出树中的各条边,边输出格式为(Ki,Kj)。例如下图所示的树。
这是西北大学考研题。这个题目主要考察考生对树的孩子兄弟表示法的理解和树的遍历算法设计思想。首先根据树结构画出孩子兄弟表示,其次再考虑如何按照以上顺序输出各条边。具体算法思想:
(1)如果为空树,则直接返回
(2)如果有子树存在,则输出这个结点的各条边
(3)然后递归调用输出兄弟结点的子树的边
(4)递归调用输出下一层所有层所有子树的边
其中(3)和(4)分别输出兄弟和下一层的边,两者顺序不能颠倒。
code:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <assert.h>
using namespace std;
typedef struct node
{
struct node* fch;
char data;
struct node* nsib;
int level;
}NODE;
typedef NODE* TREE;
#define SET(pos, c, l)\
{\
pos = (NODE*)malloc(sizeof(NODE));\
pos->data = c;\
pos->level = l;\
pos->fch = NULL;\
pos->nsib = NULL;\
return pos;\
}
void Display(TREE tree);
void ListPrintTree(TREE T);
TREE InitTree()
{
TREE tree;
SET(tree, '\0', 0);
}
void ReleaseTree(TREE tree)
{
assert(tree);
if (tree->fch!=NULL)
{
ReleaseTree(tree->fch);
}
if (tree->nsib!=NULL)
{
ReleaseTree(tree->nsib);
}
free(tree);
}
TREE Insert(TREE tree, char data, int level)
{
assert(tree);
if (tree->level==level-1)
{
SET(tree->fch, data, level);
}
if (tree->level==level)
{
SET(tree->nsib, data, level);
}
return NULL;
}
void main()
{
TREE T = InitTree(), temp1, temp2, temp3, temp4;
temp1 = Insert(T, 'A', 1);
temp2 = Insert(temp1, 'B', 2);
temp3 = Insert(temp2, 'C', 2);
Insert(temp3, 'D', 2);
temp4 = Insert(temp2, 'E', 3);
Insert(temp4, 'F', 3);
Insert(temp3, 'G', 3);
cout << "树的各条边分别是:" << endl;
Display(T->fch);
cout << endl;
cout << "以广义表形式输出树结构:\n" << endl;
ListPrintTree(T);
cout << endl;
ReleaseTree(T);
system("pause");
}
void Display(TREE tree)
{
NODE* p;
if (tree==NULL)
{
return;
}
if (tree->fch!=NULL)
{
for (p = tree->fch; p != NULL;p=p->nsib)
{
printf("%c%c,",tree->data,p->data);
}
}
if (tree->nsib!=NULL)
{
Display(tree->nsib);
}
if (tree->fch!=NULL)
{
Display(tree->fch);
}
}
void ListPrintTree(TREE T)
{
TREE p;
if (T==NULL)
{
return;
}
cout << T->data;
p = T->fch;
if (p!=NULL)
{
cout << "(";
ListPrintTree(p);
p = p->nsib;
while (p!=NULL)
{
cout << ",";
ListPrintTree(p);
p = p->nsib;
}
cout << ")";
}
}
结果: