创建二叉树及二叉树三种遍历(中)

准备工作一览

完成了一些必要的工具后,接下来考虑二叉树的创建,这里采用自动状态变迁图的方法的完成对二叉树表达式的判断

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;
}

在这里插入图片描述

根据这个框架,接下来完成二叉树的创建和遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值