前序遍历

二叉树遍历

孤街浪徒 提交于 2019-11-29 23:51:32
前序遍历:根->左->右 中序遍历:左->根->右 后序遍历:左->右->根 假设树节点的定义如下: struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; 递归版 //前序遍历 void preorderTraversalRecursion(TreeNode *node) { if(!node) return; cout << node->val << " ";//操作当前节点 preorderTraversalRecursion(node->left); preorderTraversalRecursion(node->right); } //中序遍历 void inorderTraversalRecursion(TreeNode *node) { if(!node) return; inorderTraversalRecursion(node->left); cout << node->val << " ";//操作当前节点 inorderTraversalRecursion(node->right); } //后序遍历 void postorderTraversalRecursion(TreeNode

树的递归和非递归遍历

ε祈祈猫儿з 提交于 2019-11-29 23:41:38
利用循环和栈实现前序、中序和后序遍历、利用队列实现层次遍历 typedef struct node { int data; int cnt;//在后序遍历中使用,子树的根节点在第一次遍历的时候不会输出,只有在第二次遍历的时候才输出。 struct node *lchild; struct node *rchild; }bitree; stack<node*> s; 前序遍历 //针对一个根结点,先输出其根结点值,再push其所有左结点,然后再弹出一个结点取其右结点作为新的根结点。 void preorder(bitree *t)//前序遍历的非递归算法 { bitree *temp = t; while(temp != NULL || !s.empty()) { //遍历所有左结点 while(temp != NULL)//先遍历左孩子,并输出。 { printf("%4d",temp->data); s.push(temp); temp = temp->lchild; } if(!s.empty())//当左孩子遍历完后,取栈顶,找右孩子。此时循环还没有结束,再遍历它的左孩子,直至孩子全部遍历结束。 { temp = s.top(); s.pop(); temp = temp->rchild; } } printf("\n"); } 中序遍历 void inorder

已知二叉树先序遍历中序遍历求其后序遍历、重建二叉树

妖精的绣舞 提交于 2019-11-29 19:31:06
已知二叉树先序遍历中序遍历求其后序遍历 (注:已知中序遍历序列和剩下两种遍历序列中的一种都可以确定二叉树,即可得到另一种遍历序列, 但是已知前序遍历和后序遍历序列并不能唯一确定二叉树,例如:preorder:AB postorder:BA,我们不能确定B是A的左子还是右子。) 二叉树的先序遍历的第一个元素总是树的根结点,而在中序遍历中,根结点在序列的中间,其左右两边分别是根结点的左右子树。 因此我们可以根据先序遍历确定根结点,然后在中序遍历中扫描根结点,同时可得到左右子树的中序遍历和先序遍历,递归此过程,即可获得二叉树的所有结点。 而后序遍历即为根结点左子树的后序遍历+右子树的后序遍历+根结点。 递归实现思路非常简单,C++代码: string getpostorder(char* preorder, char* inorder, int length){ string str = ""; char* rootInorder; //根结点在中序遍历中的位置 int leftlength; //左子树长度 if (length <= 0||preorder==NULL||inorder==NULL)//递归边界条件 return ""; else{ leftlength = 0; rootInorder = inorder; //扫描根结点 while (leftlength <

python实现基础的数据结构(二)

非 Y 不嫁゛ 提交于 2019-11-29 18:33:55
本文涉及到的代码均已放置在我的github中 --> 链接 python实现基础的数据结构(一) python实现基础的数据结构(二) python实现基础的数据结构(三) python语法较为简洁,正好最近在复习数据结构,索性就用python去实现吧😀 本文实现的有线性表、栈、队列、串、二叉树、图、排序算法。参照教材为 数据结构(C语言版)清华大学出版社 ,还有网上的一些大神的见解。由于包含代码在内,所以内容很多,分了几篇,话不多说,我们直接步入正题🙈 注:本文实验环境:Anaconda 集成 python 3.6.5 ( 故代码为 python3 ) 由于本文代码过多,故每一步不做太详细的介绍,我尽量在代码中解释细节,望体谅 串 串是由零个或者多个字符组成的优先序列,一般记为是s = ‘a1a2…an’ ,python对字符串的操作已经比较成熟和简单,所以我们这里着重介绍串的模式匹配算法,这就不得不提KMP匹配算法,这种算法和正则表达式有类似之处,一个用了DFA的思想,一个用了NFA的思想。 KMP算法的思想是,当匹配失败时,可以利用已经知晓的一部分文本内容,避免从头开始重新匹配。这个匹配的过程可以使用有限状态自动机(DFA)。可以看看 这位大神 的描述。 每当一趟匹配过程中出现字符比较不等时,不需要回溯I指针,而是利用已经的带的“部分匹配

二叉树

大兔子大兔子 提交于 2019-11-29 17:33:30
1.1 二叉树的定义:   二叉树 是一种特殊的树,它具有以下 特点 :   (1)树中每个节点最多只能有两棵树,即每个节点的度最多为2。   (2)二叉树的子树有左右之分,即 左子树 与 右子树 ,次序不能颠倒。   (3)二叉树即使只有一个子树时,也要区分是左子树还是右子树。    1.2 满二叉树:   满二叉树 作为一种特殊的二叉树,它是指:所有的分支节点都存在左子树与右子树,并且所有的叶子节点都在同一层上。其 特点 有:   (1)叶子节点只能出现在最下面一层   (2)非叶子节点度一定是2   (3)在同样深度的二叉树中,满二叉树的节点个数最多,节点个数为: 2 h − 1 2h−1 ,其中 h h 为树的深度。       1.3 完全二叉树:   若设二叉树的深度为 h h ,除第 h h 层外,其它各层 ( 1 ~ h − 1 ) (1~h−1) 的结点数都达到最大个数,第 h h 层所有的结点都连续集中在最左边,这就是 完全二叉树 。其具有以下 特点 :   (1)叶子节点可以出现在最后一层或倒数第二层。   (2)最后一层的叶子节点一定集中在左部连续位置。   (3)完全二叉树严格按层序编号。(可利用数组或列表进行实现,满二叉树同)   (4)若一个节点为叶子节点,那么编号比其大的节点均为叶子节点。    二、二叉树的相关性质   2.1 二叉树性质:   

前序遍历和中序遍历树构造二叉树

白昼怎懂夜的黑 提交于 2019-11-29 15:39:41
根据中序遍历和后序遍历树构造二叉树 样例 样例 1: 输入:[],[] 输出:{} 解释: 二叉树为空 样例 2: 输入:[1,2,3],[1,3,2] 输出:{2,1,3} 解释: 二叉树如下 2 / \ 1 3 注意事项 你可以假设树中不存在相同数值的节点 /** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } * } */ class Solution { public: /** *@param preorder : A list of integers that preorder traversal of a tree *@param inorder : A list of integers that inorder traversal of a tree *@return : Root of a tree */ TreeNode * buildTree(vector<int> &preorder, vector<int> &inorder) { // write your code

二叉树算法题

断了今生、忘了曾经 提交于 2019-11-29 15:20:30
二叉树层次遍历 //思路 特殊情况 ,根节点为null,深度为0,return 0 借助队列,队列储存每一层的所有节点, 先保存数组长度,用于控制依次遍历循环——遍历每一个节点保存值,该节点的所有子结点从队尾入队,访问过的节点从头出队 注意——需要先把width存下来,用于for循环的结束标志,因为for循环里面直接操作了queue,不能去都不敢动态获取 队列初始值为root,对每一层都要进行上述遍历——while循环控制,队列空代表叶节点这一层遍历完成,此时遍历结束,退出循环 每次循环开始前初始化一个curNodes储存该层所有节点,每次循环结束,将curNodes压入result var levelOrder = function(root) { if (root === null) return []; //空树 var result = [], queue = [root]; while (queue.length) { let width = queue.length; //需要先把width存下来,用于for循环,for循环里面直接操作了数组 let curNodes = []; for (let i = 0; i < width; i++) { let node = queue.shift(); curNodes.push(node.val); node.left ?

二叉树的递归与非递归遍历

為{幸葍}努か 提交于 2019-11-29 08:18:53
二叉树的递归与非递归遍历 前序遍历二叉树 递归遍历 非递归遍历 中序遍历二叉树 递归遍历 非递归遍历 后序遍历二叉树 递归遍历 非递归遍历 将二叉树遍历的结果保存到vector中返回。 递归遍历代码简短,也相对容易理解,此不赘述。咱们重点来看一下非递归遍历。 前序遍历二叉树 递归遍历 void preORecursive(TreeNode* pRoot, vector<int>& vec) { if(pRoot == NULL) return; vec.push_back(pRoot->val); preORecursive(pRoot->left, vec); preORecursive(pRoot->right, vec); } vector<int> preOrderRecursive(TreeNode* pRoot) { vector<int> vec; if(pRoot == NULL) return vec; preORecursive(pRoot, vec); return vec; } 非递归遍历 思想: 栈后法,右左子孩子入栈法 ///栈后法,右左子孩子入栈法 vector<int> preOrder(TreeNode* pRoot) { vector<int> vec; stack<TreeNode*> sta; if(pRoot) { vec.push

二叉树遍历(前、中、后序及层序遍历)

倾然丶 夕夏残阳落幕 提交于 2019-11-29 06:57:37
二叉树的遍历 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个节点均做一次且仅做一次的访问。访问节点所做的操作依赖于具体的应用问题。遍历是二叉树上最重要的运算之一。是二叉树上进行其它运算的基础。 如何将所有节点都遍历打印出来?经典的方法有三种:前序遍历、中序遍历、后序遍历。除此之外,还有按层遍历。其中,前、中、后序表示的是节点和它左右子树节点遍历打印的先后顺序。 前序遍历是指,对树中的任意节点,先打印这个节点本身,然后再打印它的左子树,最后打印它的右子树。 中序遍历是指,对树中的任意节点,先打印它的左子树,然后再打印这个节点本身,最后打印它的右子树。 后序遍历是指,对树中的任意节点,先打印它的左子树,然后再打印它的右子树,最后打印这个节点本身。 层次遍历是指,从第一层(根节点)开始,从上到下一层一层遍历,同层之间按从左到右的顺序依次遍历节点。 实际上,二叉树的前、中、后序遍历就是一个递归的过程。比如,前序遍历就是先打印根节点,然后再递归的打印左子树,最后递归的打印右子树。 二叉树的前、中、后序遍历的递归实现: /** Java版 * public class TreeNode{ * int val; * TreeNode left; * TreeNode right; * TreeNode(int x){ val = x; } */ // 前序遍历 public

(19)Go队列思想实现二叉树的非递归前序和层次遍历

[亡魂溺海] 提交于 2019-11-29 06:35:14
leetcode-144 // 用非递归法实现前序遍历,借用go自带的list实现栈的效果 // go自带的list,推进去的值被包装在element结构里面,element.Value为推进去的值 func preorderTraversal(root *TreeNode) []int { if root == nil { return nil } resp := []int{} // list底层用双链表实现,对头部尾部的插入取出删除操作时间复杂度都是O(1) l := list.New() // 从头部插入数据 l.PushFront(root) for l.Len() != 0 { // 从头部取出数据,先进后出队列(栈) e := l.Front() // list底层取出元素后元素不会删除,进行1步删除操作 l.Remove(e) // 断言判定类型 r, ok := e.Value.(*TreeNode) if ok { resp = append(resp, r.Val) } // 先进后出,右先进 if r.Right != nil { l.PushFront(r.Right) } if r.Left != nil { l.PushFront(r.Left) } } return resp } 提交leetcode,通过 leetcode-102 方法1