要求:一棵二叉树可以按照如下规则表示成一个由0、1、2组成的字符序列,我们称之为“二叉树序列S”:
例如,图1所表示的二叉树可以用二叉树序列S=21200110来表示。
图1 二叉树序列示意图
任务是要对一棵二叉树的节点进行染色。每个节点可以被染成红色、绿色或蓝色。并且,一个节点与其子节点的颜色必须不同,如果该节点有两个子节点,那么这两个子节点的颜色也必须不相同。给定一棵二叉树的二叉树序列,请求出这棵树中最多和最少有多少个点能够被染成绿色。
#include<iostream>
using namespace std;
static int i = -1;
//树的节点,包含节点及其颜色
struct Treep
{
char data;
int color;
Treep *right;
Treep *left;
};
//转换字符到整型
int Change(char A) {
int a;
a = (int)(A) - 48;
return a;
}
//求字符数组的长度
int Length(char *S) {
int n = 0;
while (*(S + n) != '\0') {
n++;
}
return n;
}
//创建二叉树
Treep* Create(char *S) {
Treep *T = new Treep;
i = i + 1;
if (i >= Length(S)) return NULL;
T->color = Change(S[i]);
T->data = S[i];
if (Change(S[i]) == 0) {
T->left = NULL;
T->right = NULL;
return T;
}
else {
if (Change(S[i]) == 1) {
T->left = Create(S);
T->right = NULL;
}
if (Change(S[i]) == 2) {
T->left = Create(S);
T->right = Create(S);
}
return T;
}
}
//判断两个数是否相等
bool judge2(int a, int b) {
return a != b;
}
//判断三个数是否相等
bool judge3(int a, int b, int c) {
return (a != c && b != c);
}
//对树进行染色
void pre_order(Treep *&T,int *A){
if (T != NULL)
{
A[T->color]++;
if (T->left != NULL) {
if (judge2(T->left->color, T->color) != true) {
T->left->color = (T->left->color + 1) % 3;
if (T->right != NULL) {
while (judge3(T->color, T->left->color, T->right->color) != true) {
T->right->color = (T->right->color + 1) % 3;
}
}
}
}
else {
if (T->right != NULL) {
if (judge2(T->color, T->right->color) != true) {
T->right->color = (T->right->color + 1) % 3;
}
}
}
pre_order(T->left,A);//递归左子树
pre_order(T->right,A);//递归右子树
}
}
//求所用的最大及最小的数量
void print(int *A) {
int max = A[0], min = A[0];
for (int i = 0; i < 3; i++) {
if (max < A[i]) max = A[i];
if (min > A[i])min = A[i];
}
cout << "绿色最大数目为:" << max << endl;
cout << "绿色最小数目为:" << min << endl;
}
int main() {
char S[20];
cout << "请输入度数序列:";
cin >> S;
int A[3] = { 0 };
Treep *root = Create(S);
pre_order(root, A);
print(A);
system("pause");
return 0;
}