准备工作一览
完成了一些必要的工具后,接下来考虑二叉树的创建,这里采用自动状态变迁图的方法的完成对二叉树表达式的判断
1- 自动状态变迁图的简介
当由用户从键盘使用gets()函数输入一个字符串时,用来判断该字符串是否合理,且进行必要的操作,如 判断一个包含( )+ - * / , 字符 数字的多项式是否输入合理,并且对其计算结果,或在生成二叉树时也需要自动状态变迁图辅助,这里只讨论对一个二叉树表达式的输入是否合理进行判断
2- 自动状态变迁图的原理
先思考并画出可能存在的所有状态,使用循环,一个个的处理字符,对于每个字符进行判断,且进行它所对应的下一状态,进行相应的操作,再处理下一个字符
3- 根据一颗二叉树画出其自动状态变迁图
规定:采用先根序输入的规则,使用 ( 和 ) 来分隔结点,使用 , 来区分左右孩子,用户从键盘输入一个字符串,包含字母,括号,逗号,程序判断该字符串是否合理(不合理状况:字母连续出现,右括号在前无左括号,括号不匹配,空格被计入有效字符,连续逗号无法区分左右孩子)
先根序规则:根(左子树)(右子树)
先根序:A B D F G J L K C E H I
输入示例:A ( B ( D ( F , G ) , J ( , L ( K ) ) ) , C ( E ( H , I ) ) )
分析表达式后,得到的自动状态变迁图如下:
4- 完成判断字符串的代码
//定义类型,处理状态,定义函数
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define NUMBER_STATUS_START 1
#define NUMBER_STATUS_ROOT 2 //根
#define NUMBER_STATUS_TREE 3 //子树
#define NUMBER_STATUS_DATA 4 //数据
#define NUMBER_STATUS_DOT 5 //逗号
#define NUMBER_STATUS_END 6
#define NUMBER_STATUS_RIGHT_KUOHAO 7 //右括号
typedef unsigned char boolean;
#define TRUE 1
#define FALSE 0
typedef struct NUMBER_ARG{
int index;
boolean ok;
boolean finished
int status;
}NUMBER_ARG;
boolean dealTheStr(char *str);
void dealTheStatusStart(char ch, NUMBER_ARG *arg);
void dealTheStatusROOT(char ch, NUMBER_ARG *arg);
void dealTheStatusTree(char ch, NUMBER_ARG *arg);
void dealTheStatusData(char ch, NUMBER_ARG *arg);
void dealTheStatusDot(char ch, NUMBER_ARG *arg);
void dealTheStatusRightKuoHao(char ch, NUMBER_ARG *arg);
void dealTheStatusEnd(char ch, NUMBER_ARG *arg);
boolean isData(char ch);
boolean isDot(char ch);
boolean isLeftKuoHao(char ch);
boolean isRightKuoHao(char ch);
boolean isOver(char ch);
//对每个字符的单独判断
boolean isOver(char ch) {
if(ch == '0') {
return TRUE;
}else {
;
}
}
boolean isRightKuoHao(char ch) {
if(ch == ')') {
return TRUE;
}else {
return FALSE;
}
}
boolean isLeftKuoHao(char ch) {
if(ch == '(') {
return TRUE;
}else {
return FALSE;
}
}
boolean isDot(char ch) {
if(ch == ',') {
return TRUE;
}else {
return FALSE;
}
}
boolean isData(char ch) {
if(ch == 'A' || ch == 'B' || ch == 'C' || ch == 'D' || ch == 'E' ||
ch == 'F' || ch == 'G' || ch == 'H' || ch == 'I' || ch == 'J' ||
ch == 'K' || ch == 'L' || ch == 'M' || ch == 'O' || ch == 'N' ||
ch == 'P' || ch == 'Q' || ch == 'R' || ch == 'S' || ch == 'T' ||
ch == 'U' || ch == 'V' || ch == 'W' || ch == 'X' || ch == 'Y' || ch == 'Z') {
return TRUE;
}else {
return FALSE;
}
}
//对各种字符判断后转入相对的状态,并进行必要的操作
void dealTheStatusEnd(char ch, NUMBER_ARG *arg) {
arg->finished = TRUE;
}
void dealTheStatusRightKuoHao(char ch, NUMBER_ARG *arg){
if(isData(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isLeftKuoHao(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isRightKuoHao(ch)) {
arg->status = NUMBER_STATUS_RIGHT_KUOHAO;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isDot(ch)) {
arg->status = NUMBER_STATUS_DOT;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isOver(ch)) {
arg->finished = TRUE;
}
}
void dealTheStatusDot(char ch, NUMBER_ARG *arg) {
if(isData(ch)) {
arg->status = NUMBER_STATUS_DATA;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isLeftKuoHao(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isRightKuoHao(ch)) {
arg->status = NUMBER_STATUS_RIGHT_KUOHAO;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isDot(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isOver(ch)) {
arg->finished = TRUE;
}
}
void dealTheStatusData(char ch, NUMBER_ARG *arg){
if(isData(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isLeftKuoHao(ch)) {
arg->status = NUMBER_STATUS_TREE;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isRightKuoHao(ch)) {
arg->status = NUMBER_STATUS_RIGHT_KUOHAO;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isDot(ch)) {
arg->status = NUMBER_STATUS_DOT;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isOver(ch)) {
arg->finished = TRUE;
}
}
void dealTheStatusTree(char ch, NUMBER_ARG *arg) {
if(isData(ch)) {
arg->status = NUMBER_STATUS_DATA;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isLeftKuoHao(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isRightKuoHao(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isDot(ch)) {
arg->status = NUMBER_STATUS_DOT;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isOver(ch)) {
arg->finished = TRUE;
}
}
void dealTheStatusROOT(char ch, NUMBER_ARG *arg) {
if(isData(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isLeftKuoHao(ch)) {
arg->status = NUMBER_STATUS_TREE;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isRightKuoHao(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isDot(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isOver(ch)) {
arg->finished = TRUE;
}
}
void dealTheStatusStart(char ch, NUMBER_ARG *arg) {
if(isData(ch)) {
arg->status = NUMBER_STATUS_ROOT;
arg->ok = TRUE;
arg->finished = FALSE;
arg->index++;
//TODO 必要操作
}else if(isLeftKuoHao(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isRightKuoHao(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isDot(ch)) {
arg->status = NUMBER_STATUS_END;
arg->ok = FALSE;
arg->finished = TRUE;
}else if(isOver(ch)) {
arg->finished = TRUE;
}
}
//处理字符串的函数
boolean dealTheStr(char *str) {
NUMBER_ARG arg = { //移动下标,判断本次输入是否合法
0, //判断循环是否结束, 判断当前字符状态
TRUE,
FALSE,
NUMBER_STATUS_START,
};
char ch;
while(arg.ok && !arg.finished) {
ch = str[arg.index];
if(NUMBER_STATUS_START == arg.status) {
dealTheStatusStart(ch, &arg);
}else if(NUMBER_STATUS_ROOT == arg.status) {
dealTheStatusROOT(ch, &arg);
}else if(NUMBER_STATUS_TREE == arg.status) {
dealTheStatusTree(ch, &arg);
}else if(NUMBER_STATUS_DATA == arg.status) {
dealTheStatusData(ch, &arg);
}else if(NUMBER_STATUS_DOT == arg.status) {
dealTheStatusDot(ch, &arg);
}else if(NUMBER_STATUS_RIGHT_KUOHAO == arg.status) {
dealTheStatusRightKuoHao(ch, &arg);
}else if(NUMBER_STATUS_END == arg.status) {
dealTheStatusEnd(ch, &arg);
}
}
return arg.ok;
}
int main(int argc, char const *argv[]) {
char str[80] = {0};
printf("请输入一个二叉树表达式,末尾加‘0’结束输入\n");
gets(str);
_flushall();
if(TRUE == dealTheStr(str)) {
printf("合法的二叉树表达式\n");
}else {
printf("非法的二叉树表达式\n");
}
return 0;
}
根据这个框架,接下来完成二叉树的创建和遍历