栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

二叉树判断同构的非递归算法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二叉树判断同构的非递归算法

关键问题是解决怎么判断两个同为倒Y形状的二叉树同构

        A                        B

C            D          E            F

如上图,怎么判断这两棵同构? 如果C在右边EF里面找到了同构,D再和EF的另一个匹配成功,就说明这两棵树同构。 实现:用栈存放两棵树上遍历指针指向的度均为2的节点,以及该节点下的子树(无分左右)被访问了几次,以及每次访问子树传回来的子树同构布尔值。这样,重复访问同一Y形节点就能区分开了,而且每一次访问子树都会向该Y形点传回bool,根据次数和bool就能很好的实现这种节点行为的 树状图(仔细一想,其实都是在围绕树状图展开,树状图需要什么,就增加对应的条件)
status is_omorphism2(BiTree t1, BiTree t2) {
	
	sqStack<::tuple<::tuple, sqStack>> sqs;
	initStack(sqs);
	::tuple traPtr = { t1,t2 };//遍历指针,允许为空
	::tuple<::tuple, sqStack> info;//用来接收栈顶节点信息,//size(关键节点的“访问栈”不允许退栈,容量等价访问次数)
	while ((t1 && t2) || !emptyStack(sqs)) {//这个scope里面执行一次有两种结果{继续向下挖,向上反馈结果},向下挖的已经写好了,向上反馈的可以用一个bool承载信息,在本scope的末尾统一上传
		bool FEEDBACK;
		if (traPtr.A && traPtr.B) {
			if (traPtr.A->lChild && traPtr.A->rChild && traPtr.B->lChild && traPtr.B->rChild) {
				//两个遍历指针都各自有两个孩子
				if ((getSize(sqs) && getTop_withQuot(sqs).A.A != traPtr.A) || (!getSize(sqs))) {//第一次访问关键节点
					sqStack boolStack;
					initStack(boolStack);
					push(sqs, { traPtr,boolStack });
					traPtr = { traPtr.A->lChild,traPtr.B->lChild };
					continue;
				}
				getTop(sqs, info);//不同访问次数之间需要共享信息,使用栈堆叠
				if (getSize(info.B) == 1) {//第一次子树匹配返回
					if (getTop_withQuot(info.B)) {//右匹配右
						traPtr = { traPtr.A->rChild,traPtr.B->rChild };
						continue;
					}
					else {//左匹配右
						traPtr = { traPtr.A->lChild,traPtr.B->rChild };
						continue;
					}
				}
				if (getSize(info.B) == 2) {//第二次匹配返回,需要用到第一次返回的情况
					if (info.B.data[0]) {//第一次返回true
						if (info.B.data[1]) {//本关键点判断同构
							FEEDBACK = true;
						}
						else {//本关键点判断不同构
							FEEDBACK = false;
						}
					}
					else {
						if (info.B.data[1]) {//右左匹配
							traPtr = { traPtr.A->rChild,traPtr.B->lChild };
							continue;
						}
						else {//本关键点不同构
							FEEDBACK = false;
						}
					}
				}
				if (getSize(info.B) == 3) {
					if (info.B.data[2]) {//本关键点同构
						FEEDBACK = true;
					}
					else {//本关键点不同构
						FEEDBACK = false;
					}
				}
			}
			else if ((traPtr.A->lChild && traPtr.A->rChild) == 0 && (traPtr.B->lChild && traPtr.B->rChild) == 0 && (traPtr.A->lChild || traPtr.A->rChild) && (traPtr.B->lChild || traPtr.B->rChild)) {
				//两指针都各有一个孩子,遍历指针指向他们实际存在的孩子
				traPtr.A = traPtr.A->rChild;
				if (traPtr.A->lChild) {
					traPtr.A = traPtr.A->lChild;
				}
				traPtr.B = traPtr.B->rChild;
				if (traPtr.B->lChild) {
					traPtr.B = traPtr.B->lChild;
				}
				continue;
			}
			else if ((!traPtr.A->lChild) && (!traPtr.A->rChild) && (!traPtr.B->lChild) && (!traPtr.B->rChild)) {
				//两指针都没有孩子,返回本子树匹配正常
				FEEDBACK = true;
			}
			else {
				//向最近关键点返回本子树匹配异常
				FEEDBACK = false;
			}
		}
		else if (!(traPtr.A && traPtr.B) && (traPtr.A || traPtr.B)) {
			FEEDBACK = false;
		}
		else {
			FEEDBACK = true;
		}
//######根据上述code特点,可以把反馈的信号放在末尾一并处理
		if (getSize(sqs) > 2) {
			pop(sqs, info);
			push(getTop_withQuot(sqs).B, FEEDBACK);
			traPtr = { getTop_withQuot(sqs).A.A,getTop_withQuot(sqs).A.B };
			continue;
		}
		else
			return FEEDBACK;//整棵树同构
	}
	return FALSE;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1040306.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号