Binary Tree
二叉树的定义
在电脑科学中,二叉树(英语:Binary tree)是每个节点最多只有两个分支(即不存在分支度大于2的节点)的树结构[1]。通常分支被称作“左子树”或“右子树”。二叉树的分支具有左右次序,不能随意颠倒。
二叉树的第i层至多拥有2i−1个节点;深度为k的二叉树至多总共有2k+1−1个节点(定义根节点所在深度 k0=0!),而总计拥有节点数符合的,称为“满二叉树”;深度为k有n个节点的二叉树,当且仅当其中的每一节点,都可以和深度k的满二叉树,序号1到n的节点一对一对应时,称为完全二叉树。对任何一棵非空的二叉树T,如果其叶片(终端节点)数为n0,分支度为2的节点数为n2,则n0=n2+1。
二叉树的发展历史
- 早期背景和数学基础:
- 在计算机科学发展之前,树结构的概念已经在数学中存在。数学家和图论专家研究了树的性质和特点。
- 计算机科学的发展从20世纪中期开始,数据结构和算法的研究逐渐兴起。
- 20世纪50年代:
- 二叉树在计算机科学中开始被正式研究和应用。1950年代是二叉树概念的形成时期。
- 当时的计算机科学家开始研究如何有效地存储和检索数据,二叉树被发现是一种有效的数据结构,尤其是在实现搜索和排序操作时。
- 二叉搜索树 (BST):
- 二叉搜索树是一种特殊的二叉树,其中左子节点的值总是小于父节点的值,右子节点的值总是大于父节点的值。
- 1959年,二叉搜索树的概念被正式提出,成为一种广泛使用的数据结构,用于高效的数据查找和排序。
- 自平衡二叉树:
- 1962年,G.M. Adelson-Velsky 和 E.M. Landis 提出了 AVL树,这是第一种自平衡二叉搜索树。AVL树通过在插入和删除节点时进行旋转操作,保持树的平衡,从而保证了操作的时间复杂度为O(log n)。
- 1972年,Rudolf Bayer 发明了红黑树,这是一种自平衡二叉搜索树,进一步提高了效率和稳定性。
- 其他变体和应用:
- 随着计算机科学的发展,二叉树的其他变体(如堆、B树、Trie树等)被广泛研究和应用在不同的领域,如数据库、编译器、网络路由等。
- 二叉树在算法设计、数据压缩(如哈夫曼编码)、表达式解析和计算等方面有着广泛的应用。
二叉树的种类
根据结构和性质的不同,二叉树可以分为许多种类。以下是一些常见的二叉树种类及其特点:
- 完全二叉树(Complete Binary Tree)
- 定义:除了最后一层外,其他每一层的节点数都达到最大,且最后一层的节点都集中在最左边。
- 特点:叶子节点只能出现在最后两层,并且最后一层的叶子节点都靠左排列。
- 满二叉树(Full Binary Tree)
- 定义:每个节点要么有两个子节点,要么没有子节点。
- 特点:叶子节点都在同一层,且每个非叶子节点都有两个子节点。
- 平衡二叉树(Balanced Binary Tree)
- 定义:任意节点的左右子树的高度差不超过1。
- 特点:为了保证查找、插入和删除操作的时间复杂度保持在 O(log n) 级别。
- 二叉搜索树(Binary Search Tree,BST)
- 定义:对任意节点,左子树上所有节点的值都小于该节点的值,右子树上所有节点的值都大于该节点的值。
- 特点:支持高效的查找、插入和删除操作。
总结
二叉树还有很多其他种类,每种都有其特定的用途和性质。根据具体应用场景选择合适的二叉树可以提高算法的效率和性能。
二叉树的重要性
- 高效查找:二叉搜索树允许在平均O(log n)的时间内进行查找操作。
- 排序功能:通过中序遍历二叉搜索树,可以获得有序的数据序列。
- 灵活性和扩展性:二叉树的变体(如AVL树、红黑树、B树等)在保持效率的同时,适应不同的应用场景和需求。
- 基础性:二叉树是很多复杂数据结构和算法的基础,如图的遍历、表达式解析、哈夫曼编码等。
综上所述,二叉树作为一种基础的数据结构,在计算机科学的发展中起到了重要的作用。从最初的数学概念到如今各种复杂的变体和应用,二叉树一直是计算机科学研究和应用的核心部分。
二叉树在内存中的储存
二叉树在内存中,使用链式存储。
也有线性存储,即使用数组来存储。
假设我们在一个32位系统上,int 和指针都占用4个字节(32位)。我们将val设置为42,并假设left和right指针为空(即NULL)。
在二进制位模式下:
42 的二进制表示是 00000000 00000000 00000000 00101010。
NULL 的二进制表示是 00000000 00000000 00000000 00000000。
因此,内存布局将是:
地址: 0x1000 0x1004 0x1008 0x100C
+--------+--------+--------+--------+
值: | 42 | NULL | NULL |
+--------+--------+--------+--------+
字段: | val | left | right |
+--------+--------+--------+--------+
64位系统中,val值不够长度会进行补齐,保持长度和后面的指针一致。