先序遍历

静态创建二叉树及其遍历

对着背影说爱祢 提交于 2019-12-03 10:07:52
我们以这个二叉树为例 1.构造二叉树的链式存储结构 1 struct BTNode{ 2 char data; //结点数据域 3 struct BTNode * pLchild; //左孩子指针-->指向左孩子 4 struct BTNode * pRchild; //右孩子指针-->指向右孩子 5 }; View Code 2.静态的创建二叉树 struct BTNode * createBTree() { struct BTNode* pa = (struct BTNode*)malloc(sizeof(struct BTNode)); struct BTNode* pb = (struct BTNode*)malloc(sizeof(struct BTNode)); struct BTNode* pc = (struct BTNode*)malloc(sizeof(struct BTNode)); struct BTNode* pd = (struct BTNode*)malloc(sizeof(struct BTNode)); struct BTNode* pe = (struct BTNode*)malloc(sizeof(struct BTNode)); pa->data = 'A'; pb->data = 'B'; pc->data = 'C'; pd->data

二叉树的深度优先遍历和广度优先遍历

你离开我真会死。 提交于 2019-12-03 04:30:07
1. 分析 二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历、中序遍历、后序遍历。具体说明如下: 先序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树。 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树。 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。 广度优先遍历:又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。 2. 举例说明 对下图所示的二叉排序树进行遍历,要求使用先序遍历(递归、非递归)、中序遍历(递归、非递归)、后序遍历(递归、非递归)和广度优先遍历。 2.1 参考代码 package BinaryTreeTraverseTest; import java.util.LinkedList; import java.util.Queue; /** * 二叉树的深度优先遍历和广度优先遍历 * @author Fantasy * @version 1.0 2016/10/05 - 2016/10/07 */ public class

数据结构――一些概念

匿名 (未验证) 提交于 2019-12-03 00:39:02
数据结构就是研究数据的 逻辑结构 和 物理结构 以及它们之间 相互关系 ,并对这种结构定义相应的运算,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。 数据:所有能被输入到计算机中,且能被计算机处理的符号的集合。是计算机操作的对象的总称。 数据元素:数据(集合)中的一个“个体”,数据及结构中讨论的 基本 单位 数据项:数据的不可分割的最小单位。一个数据元素可由若干个数据项组成。 数据类型:在一种程序设计语言中,变量所具有的数据种类。整型、浮点型、字符型等等 逻辑结构:数据之间的相互关系。 集合 结构中的数据元素除了同属于一种类型外,别无其它关系。 线性结构 数据元素之间一对一的关系 树形结构 数据元素之间一对多的关系 图状结构或网状结构 结构中的数据元素之间存在多对多的关系 物理结构/存储结构:数据在计算机中的表示。物理结构是描述数据具体在内存中的存储(如:顺序结构、链式结构、索引结构、哈希结构)等 在数据结构中,从逻辑上可以将其分为线性结构和非线性结构 数据结构的基本操作的设置的最重要的准则是, 实现应用程序与存储结构的独立 。实现应用程序是“逻辑结构”,存储的是“物理结构”。逻辑结构主要是对该结构操作的设定,物理结构是描述数据具体在内存中的存储(如:顺序结构、链式结构、索引结构、希哈结构)等。 顺序存储结构中,线性表的逻辑顺序和物理顺序总是一致的。但在链式存储结构中

C++ 二叉树的遍历

匿名 (未验证) 提交于 2019-12-03 00:32:02
#include <bits/stdc++.h> #define MaxSize 100 /* * Created by HarvestWu on 2018/06/19. */ using namespace std; typedef char ElemType; //定义二叉树结构 typedef struct BTNode { ElemType data; struct BTNode *lchild; struct BTNode *rchild; } BTNode; //定义存储结点指针及层号结构 typedef struct St { BTNode *p; int lno; } St; //由str串创建二树 void CreateBTNode (BTNode *&b,ElemType *str) { BTNode *St[MaxSize],*p= NULL; int top=-1, k = 0,j=0; ElemType ch; b= NULL; ch=str[j]; while (ch!='\0') { switch (ch) { case '(': top++; St[top]=p; k=1; break; case ')': top--; break; case ',': k=2; break; default: p=(BTNode *)malloc(sizeof

树相关算法(一)

匿名 (未验证) 提交于 2019-12-03 00:30:01
前言:算法竞赛中常见的树问题 (二叉)树的遍历 树的重心 树的直径 最近公共祖先(LCA) 哈夫曼树 树链剖分 一、(二叉)树的遍历 这种遍历顺序和DFS入栈的顺序很像,这种二叉树遍历方式称为先序遍历。除了先序遍历外,还有另外两种遍历,中序遍历和后序遍历。 先序遍历:访问根节点,遍历左子树,遍历右子树; 中序遍历:遍历左子树,访问根节点,遍历右子树; 后序遍历:遍历左子树,遍历右子树,访问根节点。 对于上面的那棵树,给出三种遍历方式是: 先序遍历: A->B->D->F ->G->H->I->E->C; 中序遍历:F->D->H->G->I->B->E->A->C; 后序遍历:F->H->I->G->D->E->B->C->A。 说了这么多,二叉树的遍历有什么用呢?答案是,没太大用。一般情况下是用来当做题目中的信息。对于OIer来说这些是常识,初赛会考的。 二、树的重心 树的重心,也叫树的质心。对于一棵树来说,删去该树的重心后,所有的子树的大小不会超过原树大小的二分之一。树的重心还有一个性质,是相对于树上的其他点而言的,就是删去重心后形成的所有子树中最大的一棵节点数最少。换句话说,就是删去重心后生成的多棵子树是最平衡的。一棵树的重心至多有两个。 #include<cstdio> #include<vector> #include<cstring> #include

BST树的插入,删除,查找(递归和非递归),先序,中序,后序(递归和非递归)

匿名 (未验证) 提交于 2019-12-03 00:18:01
关于二叉查找树的操作还是挺重要的,所以在此实现了BST的相关操作。 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。 首先实现BST的遍历操作吧,一般面试也喜欢问,比较重要的是各个遍历的非递归操作,在这里也就只实现非递归操作; 其中先序和中序遍历的非递归操作比较相似,主要思想就是将每个节点当做一个根节点进行操作。后序遍历稍微不同。下面进行代码的演示,以及相关解释: 首先针对先序遍历 Stack<TreeNode> snode = new Stack<>(); TreeNode p = root; while (!snode.isEmpty() || p != null) { if (p!=null) { System.out.print(p.value+" "); snode.push(p); p = p.left; }else{ TreeNode q = snode.pop(); p = q.right; } } 可以看到代码中利用了一个栈进行辅助,因为先序遍历的顺序是根-左-右,所以在向左节点进行遍历的时候,将节点输出,同时将节点放入栈中

根据先序遍历和中序遍历建立二叉树

匿名 (未验证) 提交于 2019-12-03 00:14:01
˼· 先序遍历服从规则 “根左右” ,所以由此可知,对于一个先序遍历得到的数组,第一个元素一定是 根节点 ; 中序遍历服从规则 ”左根右“ ,所以由此可知,对于一个中序遍历得到的数组,根节点左边的元素都属于根节点的 左子树 ,而根节点右边的元素都属于根节点的 右子树 ; 所以,我们可以先通过先序遍历的第一个元素确定根节点,然后通过中序遍历结合根节点,获得当前根节点的左右子树,再将子树看成一棵独立的树,继续使用先序遍历判断根节点,中序遍历判断子树的方式,最终建立起整棵树; 假设有一棵二叉树,先序遍历为 {1,2,4,7,3,5,6,8} ,中序遍历为 {4,7,2,1,5,3,8,6} ,则建树过程如下: 首先,通过先序遍历可知树的根节点为 1 ,则在中序遍历中,1左边的元素 4,7,2 即为根的左子树的元素,而 1 右边的元素 5,3,8,6 即为根节点的右子树; 对于左子树 4,7,2 来说,在先序遍历中,这三个点的顺序为 2,4,7 ,则 2 为根节点,而在中序遍历中, 4,7 均在 2 的左边,则 4,7 均为以 2 为根树的左子树,且没有右子树; 对于 4,7 这两个节点来说,先序遍历中, 4 节点在7节点之前,所以 4 为根节点,而 7 作为子树,在中序遍历中, 7 在 4 之后,所以 7 为右子树; 对于根节点 1 的右子树 5,3,8,6 来说,在先序遍历中, 3

二叉树算法题

匿名 (未验证) 提交于 2019-12-03 00:05:01
二叉树层次遍历 //思路 特殊情况 ,根节点为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 ?

二叉树链式存储及其各种遍历和求深度、宽度(C语言实现、非递归)

匿名 (未验证) 提交于 2019-12-03 00:04:02
定义二叉树结点、栈、队列 typedef struct TNode { // 结点 int data ; struct TNode * lchild , * rchild ; } TNode , * BiTree ; typedef struct queen_node { // 循环队列 TNode * nodes [ 100 ] ; int front ; //指向队头元素的前一个(为了判别队空和判别队满) int size ; //指向队尾元素 int rear ; // 尾进头出 } queen_node , * Queen ; typedef struct stack_node { // 栈 头进头出。 TNode * nodes [ 100 ] ; int top ; // top=-1为空栈 int size ; } * Stack ; Stack init_Stack ( ) { // 初始化栈 Stack stack = ( Stack ) malloc ( sizeof ( stack_node ) ) ; stack -> top = - 1 ; stack -> size = 100 ; return stack ; } void push_stack ( Stack S , TNode * p ) { //入s栈 if ( S -> top < S ->

二叉树的创建和遍历

匿名 (未验证) 提交于 2019-12-02 23:56:01
二叉树创建:   1.创建树的结点TreeNode,包含结点的编号no,结点的名字name,左子树left,右子树right,    二叉树遍历:   1,先序遍历:先输出根节点,再递归左子树,然后递归右子树   2,中序遍历:先递归左子树,然后输入根节点,再递归右子树   3,后序遍历:先递归左子树,再递归右子树,然后输出根节点 实验:   创建如下的二叉树并遍历    代码 package Tree; public class BinaryTreeDemo { public static void main(String[] args) { BinaryTree binaryTree = new BinaryTree(); //创建结点 TreeNode root = new TreeNode(1,"宋江"); TreeNode treeNode2 = new TreeNode(2,"林冲"); TreeNode treeNode3 = new TreeNode(3,"吴用"); TreeNode treeNode4 = new TreeNode(4,"关胜"); TreeNode treeNode5 = new TreeNode(5,"卢俊义"); //创建树结构 root.setLeft(treeNode2); root.setRight(treeNode3);