数据结构整理(二) 树

一、前言

  项目源码及其他声明等参见数据结构(一)线性结构篇。

二、相关概念

  树作为一种应用广泛的一对多非线性数据结构,不仅有数据间的指向关系,还有层级关系,示例见图一。因树的结构比较复杂,为了简化操作及存储,我们一般将树转换为二叉树处理,因此本文主要讨论二叉树。

  1. 二叉树
      二叉树是每个节点最多拥有两个子节点的树结构,若移除根节点则其余节点会被分成两个互不相交的子树,分别称为左子树和右子树。二叉树是有序树,左右子树有严格的次序,若颠倒则成为一棵不一样的二叉树。
  2. 满二叉树
      
    满二叉树,顾名思义除叶子节点外所有节点都拥有两个孩子,且叶子节点在同一层的二叉树,示例见图二。
  3. 完全二叉树
      
    完全二叉树,移除最后一层节点后是满二叉树,且最后一层的节点都连续集中在最左面,示例见图三。

三、二叉树存储结构

  1. 顺序存储
      
    根据完全二叉树的特性,可以计算出任意节点n的双亲节点及左右孩子节点的序号,因此完全二叉树的节点可以按照从上到下从左到右的顺序依次存储到一维数组中。非完全二叉树存储时应先将其改造为完全二叉树,以空替代不存在的节点,比较浪费存储空间,存储示意图见图四。
  2. 链式存储
      树结构链式存储类似线性结构链式存储,先定义包含数据域和引用域的节点(Node),然后通过引用域存储节点之间的关系。根据二叉树的结构来看,节点Node至少包含数据域(Data),引用域(左孩子LChild、右孩子RChild),为了方便通过孩子节点查找父节点,引用域中可以考虑添加父节点引用(Parent),存储示意图见图五。

四、树与二叉树的转换

  1. 树转二叉树

    加线,所有兄弟结点之间加一条连线。
    抹线,对树中的每个结点,只保留他与第一个孩子结点之间的连线,删除它与其它孩子结点之间的连线。
    整理,整理前两步得到的树,使之结构层次分明。

  2. 二叉树转树

    加线,若某结点的左孩子结点存在,将左孩子结点的右孩子结点、右孩子结点的右孩子结点……都作为该结点的孩子结点,将该结点与这些右孩子结点用线连接起来。
    抹线,删除原二叉树中所有结点与其右孩子结点的连线。
    整理,整理前两步得到的树,使之结构层次分明。

五、树遍历实现

 1 /// <summary>
 2 /// 先序遍历(DLR)
 3 /// </summary>
 4 /// <![CDATA[首先访问跟节点,然后遍历左子树,最后右子树]]>
 5 static void PreOrder(Node<char> root)
 6 {
 7     if (root == null)
 8     {
 9         return;
10     }
11
12     Print(root);
13     PreOrder(root.LChild);
14     PreOrder(root.RChild);
15 }
16
17 /// <summary>
18 /// 中序遍历(LDR)
19 /// </summary>
20 /// <![CDATA[先遍历左子树,然后根节点,最后遍历右子树]]>
21 static void InOrder(Node<char> root)
22 {
23     if (root == null)
24     {
25         return;
26     }
27
28     InOrder(root.LChild);
29     Print(root);
30     InOrder(root.RChild);
31 }
32
33 /// <summary>
34 /// 后序遍历(LRD)
35 /// </summary>
36 /// <![CDATA[先遍历左子树,然后遍历右子树,最后遍历根节点]]>
37 static void PostOrder(Node<char> root)
38 {
39     if (root == null)
40     {
41         return;
42     }
43
44     PostOrder(root.LChild);
45     PostOrder(root.RChild);
46     Print(root);
47 }
48
49 /// <summary>
50 /// 层序遍历
51 /// </summary>
52 /// <![CDATA[从上向下从左到右]]>
53 static void LevelOrder(Node<char> root)
54 {
55     if (root == null)
56     {
57         return;
58     }
59     CSeqQueue<Node<char>> sq = new CSeqQueue<Node<char>>(50);
60     sq.In(root);
61     while (!sq.IsEmpty())
62     {
63         Node<char> tmp = sq.Out();
64         Print(tmp);
65
66         if (tmp.LChild != null)
67         {
68             sq.In(tmp.LChild);
69         }
70
71         if (tmp.RChild != null)
72         {
73             sq.In(tmp.RChild);
74         }
75     }
76 }
时间: 2024-10-04 21:06:50

数据结构整理(二) 树的相关文章

《数据结构》线段树入门(二)

今天继续介绍——线段树之延迟标记 接上期<数据结构>线段树入门(一):http://www.cnblogs.com/shadowland/p/5870339.html 在上期介绍了线段树的最基本内容(线段树单点修改,区间查询),这次将介绍:区间修改,区间查询. Question: 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述: 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,每行表示操作的个数,如果第一数是1,后接3个正

Java数据结构之二叉搜索树

Java数据结构之二叉搜索树 1.二叉搜索树组成 二叉搜索树又称为二叉排序树,它或者是一颗空树,或者是一颗具有如下特性的非空二叉树,需要满足一下三个条件: (1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字: (2)若它的右子树非空,则右子树上所有结点的关键字均大于(可以等于)根结点的关键字. (3)左子树右子树本身又各是一颗二叉搜索树 在算法描述中,均以结点值的比较来代表其关键字的比较,因为若结点的值为类类型时,该类必须实现系统提供的java.lang.comparable

数据结构之AVL树

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 在前面的博文中,我们已经介绍了数据结构之二分查找树的相关知识,二分查找的提出主要是为了提高数据的查找效率.同一个元素集合可以对应不同的二分查找树BST,二分查找树的形态依赖于元素的插入顺序.同时我们也已经知道,如果将一个有序的数据集依次插入到二查找树中,此时二分查找树将退化为线性表,此时查找的时间复杂度为o(n).为了防止这一问题的出现,便有了平衡二叉树的存在价值.平衡二叉树从根本上将是为了防止出现斜二叉树的出现,从而进一步提高元素的查找效率,

《ACM/ICPC 算法训练教程》读书笔记 之 数据结构(线段树详解)

依然延续第一篇读书笔记,这一篇是基于<ACM/ICPC 算法训练教程>上关于线段树的讲解的总结和修改(这本书在线段树这里Error非常多),但是总体来说这本书关于具体算法的讲解和案例都是不错的. 线段树简介 这是一种二叉搜索树,类似于区间树,是一种描述线段的树形数据结构,也是ACMer必学的一种数据结构,主要用于查询对一段数据的处理和存储查询,对时间度的优化也是较为明显的,优化后的时间复杂为O(logN).此外,线段树还可以拓展为点树,ZWK线段树等等,与此类似的还有树状数组等等. 例如:要将

【数据结构】Huffman树

参照书上写的Huffman树的代码 结构用的是线性存储的结构 不是二叉链表 里面要用到查找最小和第二小 理论上锦标赛法比较好 但是实现好麻烦啊 考虑到数据量不是很大 就直接用比较笨的先找最小 去掉最小再找第二小的方法了. #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct{ unsigned int weight; unsigned int parent, lchild, r

数据结构之二叉堆、堆排序

前言 上一篇写了数据结构之二叉搜索树.AVL自平衡树,这次来写堆. 堆的创造者 很久以前排序算法的时间复杂度一直是O(n^2), 当时学术界充斥着"排序算法不可能突破O(n^2)"的声音,直到1959年,由D.L.Shell提出了一种排序算法,希尔排序(Shell Sort),才打破了这种不可能的声音,把排序算法的时间复杂度提升到了O(n^3/2)! 当科学家们知道这种"不可能"被突破之后,又相继有了更快的排序算法,"不可能超越O(n^2)"彻底

【经典数据结构】B树与B+树

本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树.与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作.B-tree算法减少定位记录时

AJAX学习整理二之简单实例

做了几个简单的实例,加载txt文本内容.加载xml文件内容,把xml文本内容转换成html表格显示.废话不多说,直接贴代码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/html"> <head>     <title>通过ajax获取文本内容</title>     <meta charset="utf-8">     <scr

【数据结构】Trie树

1.Trie树简介 Trie树,又称字典树.前缀树,被用于信息检索(information retrieval)的数据结构.Trie一词便来自于单词retrieval.基本思想:用字符串的公共前缀降低查询时间.比如,在最优的查询二叉树中查询关键字的时间复杂度为M * log N,M是字符串最大长度,N为字符串数量:而用Trie树时,只需O(M)时间. [1] 中给出一个简单Trie树例子,蓝色表示一个单词结尾:该Trie树存储的单词为the, their, there, a, any, answ