叶子结点

List、Set、数据结构、Collections

浪子不回头ぞ 提交于 2020-02-12 19:38:34
List、Set、数据结构、Collections 数据结构 常见的数据结构 数据存储的常用结构有: 栈、队列、数组、链表和红黑树 栈 栈 : stack ,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。 简单的说:采用该结构的集合,对元素的存取有如下的特点 先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。 栈的入口、出口的都是栈的顶端位置。 需要注意两个名词: 压栈 :就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。 弹栈 :就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置。 队列 队列 : queue ,简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。 简单的说,采用该结构的集合,对元素的存取有如下的特点: 先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,小火车过山洞,车头先进去,车尾后进去;车头先出来,车尾后出来。 队列的入口、出口各占一侧。例如,下图中的左侧为入口,右侧为出口。 数组 数组 :

java 哈夫曼编码

蓝咒 提交于 2020-02-12 16:09:24
//哈夫曼树类 public class HaffmanTree { //最大权值 static final int MAXVALUE=1000; int nodeNum ; //叶子结点个数 public HaffmanTree(int n) { this.nodeNum = n; } //构造哈夫曼树算法 public void haffman(int[] weight,HaffNode[] nodes)//权值数组,所有节点数组 { int n = this.nodeNum; //m1,m2,表示最小的两个权值,x1,x2,表示最小两个权值对应的编号,m1表示最小,m2表示次小 int m1,m2,x1,x2; //初始化所有的结点,对应有n个叶子结点的哈夫曼树,有2n-1个结点。 for(int i=0;i < 2*n-1;i++) { HaffNode temp = new HaffNode(); //初始化n个叶子结点,就是输入的节点。0、1、2、3是叶子节点也是输入的节点 if(i < n) { temp.weight = weight[i]; } else { temp.weight = 0; } temp.parent = 0; temp.flag = 0; temp.leftChild = -1; temp.rightChild = -1; nodes[i] =

哈夫曼树与哈夫曼编码

怎甘沉沦 提交于 2020-02-12 13:03:57
哈夫曼树与哈夫曼编码 术语 : i)路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。 路径中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。 ii)结点的权及带权路径长度 若对树中的每个结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。 结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。 iii)树的带权路径长度 树的带权路径长度:所有 叶子结点 的带权路径长度之和,记为WPL。 先了解一下哈夫曼树,之后再构造一棵哈夫曼树,最后分析下哈夫曼树的原理。 1)哈夫曼树 哈夫曼树是这样定义的:给定n个带权值的节点,作为叶子节点,构造一颗二叉树,使树的带权路径长度达到最小,这时候的二叉树就是哈夫曼树,也叫最优二叉树。 哈夫曼树具有如下性质: 1)带权路径长度最短 2)权值较大的结点离根较近 2)构造哈夫曼树 构造哈夫曼树的步骤如下: 假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为: 1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点); 2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树, 且新树的根结点权值为其左、右子树根结点权值之和 3)从森林中删除选取的两棵树

剑指offer4-解决面试题的思路

断了今生、忘了曾经 提交于 2020-02-11 14:10:51
4.2 画图 题目-二叉树的镜像 操作给定的二叉树,将其变换为源二叉树的镜像。 思路 求二叉树镜像的过程:1)交换根结点的左右子树;2)交换值为10的结点的左右子结点;3)交换值为6的结点的左右子结点。 总结这个过程就是:前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子结点。 直到交换完所有非叶子结点的左右子结点。 解答 /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ public class Solution { public void Mirror(TreeNode root) { if((root==null) || (root.left==null && root.right==null)) return; //交换根结点的左右子树 TreeNode temp=root.left; root.left=root.right; root.right=temp; //交换原来根结点的左子结点的左右子结点 if(root.left!=null) Mirror(root.left); //交换原来根结点的右子结点的左右子结点 if(root

AVL树(Java)

余生长醉 提交于 2020-02-09 14:03:36
AVL树 在计算机科学中,AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。 特点 1.本身首先是一棵 二叉搜索树 。 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。也就是说, AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树) 平衡因子 某 结点的左子树与右子树的高度(深度)差 即为该结点的平衡因子(BF,Balance Factor)。平衡二叉树上所有结点的平衡因子只可能是 -1,0 或 1。 高度(height) 为了方便计算每一结点的平衡因子我们可以为每个节点赋予height这一属性,表示此节点的高度。 这里的高度是由叶子节点从下向上计算的,叶子节点的height是1,叶子节点的父节点height是2,以此类推。 旋转 AVL树的基本操作一般涉及运做同在不平衡的二叉查找树所运做的同样的算法。但是要进行预先或随后做一次或多次所谓的"AVL 旋转"。 假设由于在二叉排序树上插入结点而失去平衡的最小子树根结点的指针为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先结点),则失去平衡后进行进行的规律可归纳为下列四种情况: 单向右旋平衡处理LL :由于在a的左子树根结点的左子树上插入结点,a的平衡因子由1增至2

二叉树三种遍历方式的非递归实现

南楼画角 提交于 2020-02-09 07:50:11
1、二叉树的先序遍历。 节点->左孩子->右孩子 用递归很容易解决,但是会遇到内存溢出情况。用栈可以解决找个问题。 根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:   对于任一结点P: 1)访问结点P,并将结点P入栈; 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P; 3)直到P为NULL并且栈为空,则遍历结束。 1 public void xianxu(TreeNode root){ 2 Stack<TreeNode> stack = new Stack<>(); 3 TreeNode p = root; 4 while ( !stack.isEmpty() ){ 5 while ( p != null ){ 6 System.out.println(p.val); 7 stack.push(p); 8 p = p.left; 9 } 10 if ( !stack.isEmpty() ){ 11 p = stack.pop(); 12 p = p.right; 13 } 14 } 15

图解排序算法(三)之堆排序

邮差的信 提交于 2020-02-08 23:14:47
预备知识 堆排序   堆排序是利用 堆 这种数据结构而设计的一种排序算法,堆排序是一种 选择排序, 它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。 堆    堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图: 同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子 该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是: 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] 小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] ok,了解了这些定义。接下来,我们来看看堆排序的基本思想及基本步骤: 堆排序基本思想及步骤    堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了 步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。   a.假设给定无序序列结构如下 2

常用算法之----堆排序

喜欢而已 提交于 2020-02-08 22:58:34
预备知识 堆排序   堆排序是利用 堆 这种数据结构而设计的一种排序算法,堆排序是一种 选择排序, 它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。 堆    堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图: 同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子 该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是: 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] 小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] ok,了解了这些定义。接下来,我们来看看堆排序的基本思想及基本步骤: 堆排序基本思想及步骤    堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了 步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。   a.假设给定无序序列结构如下 2

图解排序算法(三)之堆排序

≡放荡痞女 提交于 2020-02-08 17:40:56
图解排序算法(三)之堆排序 预备知识 堆排序   堆排序是利用 堆 这种数据结构而设计的一种排序算法,堆排序是一种 选择排序, 它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。 堆    堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图: 同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子 该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是: 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] 小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] ok,了解了这些定义。接下来,我们来看看堆排序的基本思想及基本步骤: 堆排序基本思想及步骤    堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了 步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。   a.假设给定无序序列结构如下 2

非线性数据结构——树

微笑、不失礼 提交于 2020-02-08 16:52:52
树 非线性数据结构定义:也就是每个元素可以有多个前驱和后继。树是一种非线性结构。它可以有两种定义。 第一种:树是n(n>=0, n为0时,称为空树 )个元素的集合,它只有 一个特殊的没有前驱的元素 ,这个元素成为树的 根(root) ,而且 树中除了根节点外,其余的元素都只能有一个前驱,可以有0个或者多个后继。 第二种递归定义:树T是n(n>=0,n为0时,称为空树)个元素的集合,它有且只有一个特殊元素根,剩余元素都可以被划分为M个互不相交的集合T1,T2,T3……、Tm,而每一个集合都是树,称为T的子树subtree,同时,子树也有自己的根。 维基百科是这样定义的: 树中的概念 结点: 树中的数据元素,也就是上图中的,A,B,C,D,E,F,G…… 结点的度degree :节点拥有的子树的数目称为度,记作d(v)。 叶子结结: 节点的度为0,称为叶子节点leaf,终端节点,末端节点。 分支结点: 节点的度不为0,称为非终端节点或分支节点。 分支: 节点之间的关系。 内部节点: 除根节点外的分支节点,当然也不包括叶子节点。 树的度: 树内各节点的度的最大值,比如下面这个图D节点的度最大为3,所以树的度数就是3. 孩子(儿子child)节点: 节点的子树的根节点成为该节点的孩子。 双亲(父parent)节点: 一个节点是他各子树的根节点的双亲。 兄弟(sibling)节点: