二叉树前序中序,后序中序,公共最近祖先的实现
二叉树前序中序,后序中序,公共最近祖先的实现
注释中详细介绍了算法,故不再赘述。
无论是前序还是后序,一个节点的左子树和右子树都是可以看做是分开的,有一定规律可循,故可用递归进行实现。
#include <iostream>
#include <cstring>
#include <vector>using namespace std;const int len = 12;char pre[len] = "ABDEHCFIJGK";
char mid[len] = "DBHEAIFJCKG";typedef struct _Node{char data;struct _Node *left;struct _Node *right;
}TreeNode, *Tree;// 确定c在中序序列mid中的下标,假设树的各个节点的值各不相同
int position(char c) {return strchr(mid, c) - mid;
}/* 利用前序中序序列创建树* i: 子树的前序序列字符串的首字符在pre[]中的下标* j: 子树的中序序列字符串的首字符在mid[]中的下标* len: 子树的字符串序列的长度
*/
void premidCreateTree(Tree &node, int i, int j, int len) {if(len <= 0) {node = NULL;return;}node = new TreeNode;node->data = pre[i];int m = position(pre[i]);// i+1 :该node节点的左子树前序序列字符串的首字符在pre[]中的下标// j :该node节点的左子树中序序列字符串的首字符在mid[]中的下标// m-j :该node节点的左子树字符串序列的长度premidCreateTree(node->left, i+1, j, m-j);// i+(m-j)+1 :该node节点的右子树前序序列字符串的首字符在pre[]中的下标// m+1 :该node节点的右子树中序序列字符串的首字符在mid[]中的下标// len-1-(m-j):该node节点的右子树字符串序列的长度premidCreateTree(node->right, i+(m-j)+1, m+1, len-1-(m-j));
}// 前序遍历树
void PreTravelTree(Tree &node) {if(node) {cout << node->data;PreTravelTree(node->left);PreTravelTree(node->right);}
}/* 利用后序中序序列创建树* i: 子树的后序序列字符串的尾字符在post[]中的下标* j: 子树的中序序列字符串的首字符在mid[]中的下标* len: 子树的字符串序列的长度*/
void PostMidCreateTree(PNode &pn, int i, int j, int len) {if(len <= 0) {node = NULL;return;}pn = new Node;pn->v = post[i];int m = Position(post[i]);PostMidCreateTree(pn->left, i-1-(len-1-(m-j)), j, m-j);//注意参数:m-j左子树的长度,len-1-(m-j)右子树的长度PostMidCreateTree(pn->right, i-1, m+1, len-1-(m-j));
}// 寻找两个节点的最近公共祖先,但是遇到下面这种情况时,会有bug
// A 寻找B,C的公共祖先,不能用此算法
// / \
// B D
// /
// C
int findPNode(Tree root, char a, char b, TreeNode** PNode){if(root == NULL) return 0;if(root->data == a || root->data == b) {return 1;}int left = findPNode(root->left, a, b, PNode);if(left == 2) return 2;int right = findPNode(root->right, a, b, PNode);if(right == 2) return 2;if(left + right == 2) *PNode = root;return left + right;
}// 二叉树是普通的二叉树,节点只有left/right,没有parent指针。
//
// 10
// / \
// 6 14
// / \ / \
// 4 8 12 18
// / \
// 3 5
//
// 基本思想:记录从根找到node1和node2的路径,然后再把它们的路径用类似的情况一来做分析,比如还是node1=3,node2=8这个case.
// 我们肯定可以从根节点开始找到3这个节点,同时记录下路径3,4,6,10,类似的我们也可以找到8,6,10。
// 我们把这样的信息存储到两个vector里面,把长的vector开始的多余节点3扔掉,从相同剩余长度开始比较,4!=8, 6==6,我们找到了我们的答案。bool findParentByVector(TreeNode* root, char NData, vector<TreeNode*>& path) {if(root == NULL) return false;if(root->data != NData) {if(findParentByVector(root->left, NData, path)) {path.push_back(root);return true;} else {if(findParentByVector(root->right, NData, path)) {path.push_back(root);return true;} else {return false;}}} else {path.push_back(root);return true;}
}TreeNode* findBstNode(TreeNode* root, char a, char b) {vector<TreeNode*> path1;vector<TreeNode*> path2;bool find = false;find |= findParentByVector(root, a, path1);find &= findParentByVector(root, b, path2);if(find) {int minSize = path1.size() > path2.size() ? path2.size() : path1.size();int th1 = path1.size() - minSize;int th2 = path2.size() - minSize;for(; th1 < (int)path1.size() && th2 < (int)path2.size(); th1++, th2++) {if(path1[th1] == path2[th2]) {return path1[th1];}} }return NULL;
}int main() {Tree root = NULL;premidCreateTree(root, 0, 0, strlen(mid));PreTravelTree(root);TreeNode *PNode = NULL;/*findPNode(root, 'D', 'B', &PNode);cout << endl << PNode->data << endl;*/PNode = findBstNode(root, 'I', 'G');cout << endl << PNode->data << endl;getchar();return 0;
}
二叉树前序中序,后序中序,公共最近祖先的实现相关推荐
- 二叉树前序遍历与后序遍历
二叉树 前序遍历 递归 借助栈进行排序 先将根节点压栈 栈不为空,如果存在根节点,先右后左. 弹栈打印.直至栈为空 package com.vitamin.tree;import java.util. ...
- 二叉树前序遍历,后序遍历
求前序遍历 Description 给出一棵二叉树的中序和后序遍历,求它的前序遍历.(树结点用不同的大写字母表示,长度小于等于26.) Input 本问题有多组测试数据,每组测试数据有两行,每行都是由 ...
- 二叉树前序中序后序_leetcode889_go_根据前序和后序遍历构造二叉树
leetcode889_根据前序和后序遍历构造二叉树 01 - 题目 返回与给定的前序和后序遍历匹配的任何二叉树. pre 和 post 遍历中的值是不同的正整数. 示例:输入:pre = [1,2, ...
- 二叉树前序、中序、后序遍历求法
二叉树前序.中序.后序遍历相互求法 二叉树的三种遍历方法: 前序遍历: 1.访问根节点 2.前序遍历左子树 3.前序遍历右子树 中序遍历: 1.中序遍历左子树 2.访问根节点 3.中序遍历右子树 后序 ...
- 二叉树前序、中序和后序遍历的非递归实现
1 二叉树的遍历 1.1 前序遍历 对于每棵子树,先处理根,然后处理左子树,最后处理右子树.根最先访问,所以是前序遍历. 1.2 中序遍历 对于每棵子树,先处理左子树,然后处理根,最后处理右子树.根中 ...
- 用前序中序创建二叉树(用中序后序创建二叉树)
定义二叉树结点 比如就拿这个二叉树 前序中序创建 因为前序遍历的顺序是 根 , 左 ,右. 中序的遍历是 左 根 右. 我们会很不好想,但我们可以用前序和中序把上面那个二叉树的遍历一边 前序遍历:AB ...
- 数据结构 - 顺序存储二叉树(前序中序后序遍历)
就是逻辑上是二叉树,物理上是一个数组 需求 package tree;public class ArrayBinaryTreeDemo {public static void main(String[ ...
- 二叉树前序、中序、后序遍历非递归写法的透彻解析
前言 在前两篇文章二叉树和二叉搜索树中已经涉及到了二叉树的三种遍历.递归写法,只要理解思想,几行代码.可是非递归写法却很不容易.这里特地总结下,透彻解析它们的非递归写法.其中,中序遍历的非递归写法最简 ...
- c++ 删除二叉树的子树_数据结构—树|二叉树|前序遍历、中序遍历、后序遍历【图解实现】...
点击蓝字关注我们 AI研习图书馆,发现不一样的精彩世界 数据 结构 二叉树的遍历 一.树 在谈二叉树的知识点之前,我们首先来看一下树和图的基本概念.树:不包含回路的连通无向图,树是一种简单的非线性结构 ...
- 2018.7.28 二叉树的遍历规则(前序遍历、后序遍历、中序遍历)
树的遍历顺序大体分为三种:前序遍历(先根遍历.先序遍历),中序遍历(中根遍历),后序遍历(后根遍历). 前序遍历:前序遍历可以记为根左右,若二叉树为空,则结束返回. 前序遍历的规则:(1)访问根节点( ...
最新文章
- 为什么要用MyBatis-JDBC 连接数据库
- 这谁写的技术文档?我想锤死他...
- java函数式编程 map_函数式编程-对Java 8流进行分区
- Windows Moible, Wince 使用.NET Compact Framework的进行蓝牙(Bluetooth)设备配对的开发
- php request对象,PHP 中TP5 Request 请求对象的实例详解
- DOCTYPE 声明
- CoreAnimation-CATransform3D特效
- nuget.org 无法加载源 https://api.nuget.org/v3/index.json 的服务索引
- python爬取58同城房子发布的手机号码_python爬虫:爬取58同城武汉地区商品房信息(最后碰到了58同城的反爬机制,吓得我不敢说话···)...
- 自动驾驶 9-5: EKF 的局限性 Limitations of the EKF
- 中学计算机基础知识,初中信息技术学业水平考试计算机基础知识考点大全(重点汇总)...
- (Python数字图像处理)自适应中值滤波算法
- Java 正则表达式的用法和实例
- .NET 6 运行在Win7 SP1上出错
- MDK 使用 ST-Link 下载出现 target dll has been cancelled 的错误的解决方法
- 【详细图解】七彩虹智能主板的开机键连接线怎么插 | 七彩虹主板的前置音频接线法怎么插 | 七彩虹2.0主板 F_PANEL怎样插
- 开一间煎饼果子店能挣多少钱?
- windows 10 时间同步,时间显示不准自动校准。
- 936烙铁芯发热芯型号判断
- 蓝奏云批量下载修复版 v0.3
热门文章
- Word2vec之CBOW模型和Skip-gram模型形象解释
- linux下部署jdk+Tomcat
- Instruments性能优化-Core Animation
- react源码解析002 - 关于babelrc
- dcloud会员激活mui
- android studio中把c/c++文件编译成.so库(一)
- ActiveReports 9实战教程(3): 图文并茂的报表形式
- 实现Windows Phone 8多媒体:视频
- 被坑;剪头发(普通修剪)180元!你会怎么办?
- Citrix 客户端登录出现wfshell.exe - 应用程序错误的解决方法