🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 完全二叉树 > 原文: [https://www.programiz.com/dsa/complete-binary-tree](https://www.programiz.com/dsa/complete-binary-tree) #### 在本教程中,您将学习完全二叉树及其不同类型。 此外,您还将在 C,C++ ,Java 和 Python 中找到完全二叉树的工作示例。 完全二叉树是一棵二叉树,其中所有级别均已完全填充,但最低级别可能会从左侧填充。 完全二叉树就像满二叉树,但有两个主要区别 1. 所有叶子元素都必须向左倾斜。 2. 最后一个叶子元素可能没有正确的同级,即完全二叉树不必是满二叉树。 ![Complete Binary Tree](https://img.kancloud.cn/0d/ef/0defa25606c039b380ecf556d210cd60_456x432.png "Complete Binary Tree") 完全二叉树 * * * ## 完全二叉树 vs 满二叉树 ![Comparison between full binary tree and complete binary tree](https://img.kancloud.cn/3e/c6/3ec629fce557d18231562f2f474101b1_496x564.png "Comparison between full binary tree and complete binary tree") 完全二叉树与满二叉树的比较 ![Comparison between full binary tree and complete binary tree](https://img.kancloud.cn/29/b0/29b0a0608f68a954effa7b0dec6afd61_446x564.png "Comparison between full binary tree and complete binary tree") 完全二叉树与满二叉树的比较 ![Comparison between full binary tree and complete binary tree](https://img.kancloud.cn/be/a6/bea6804b4fe09d6900f4a691e1fb34e0_446x564.png "Comparison between full binary tree and complete binary tree") 完全二叉树与满二叉树的比较 ![Comparison between full binary tree and complete binary tree](https://img.kancloud.cn/94/83/9483948ef3773e0be2301de649d287a7_446x564.png "Comparison between full binary tree and complete binary tree") 完全二叉树与满二叉树的比较 * * * ## 如何创建完全二叉树? 1. 选择列表的第一个元素作为根节点。 (级别 I 上的元素数:1) ![Complete binary tree creation](https://img.kancloud.cn/e0/20/e0206b57aa1fcbd5b2869a87781670e6_702x176.png "Select the first element as root") 选择第一个元素作为根 2. 将第二个元素作为根节点的左子元素,将第三个元素作为右子元素。 (第 II 级元素的数量:2) ![Complete binary tree creation](https://img.kancloud.cn/d8/32/d83265eabc382fb3188c21cb0720f4b4_862x304.png "Put the second element as a left child of the root node and the third element as the right child") 12 是左侧子级,9 是右侧子级 3. 将接下来的两个元素作为第二级左节点的子级。 同样,将接下来的两个元素作为第二层右节点的子元素(第 III 层上的元素数量:4 个)。 4. 不断重复,直到到达最后一个元素。 ![Complete binary tree creation](https://img.kancloud.cn/42/7c/427c3bd8211f62c23a547a99191c87a0_1146x432.png "Keep repeating until the last element is reached") 5 是左侧子级,6 是右侧子级 * * * ## Python,Java 和 C/C++ 示例 ```py # Checking if a binary tree is a complete binary tree in C class Node: def __init__(self, item): self.item = item self.left = None self.right = None # Count the number of nodes def count_nodes(root): if root is None: return 0 return (1 + count_nodes(root.left) + count_nodes(root.right)) # Check if the tree is complete binary tree def is_complete(root, index, numberNodes): # Check if the tree is empty if root is None: return True if index >= numberNodes: return False return (is_complete(root.left, 2 * index + 1, numberNodes) and is_complete(root.right, 2 * index + 2, numberNodes)) root = Node(1) root.left = Node(2) root.right = Node(3) root.left.left = Node(4) root.left.right = Node(5) root.right.left = Node(6) node_count = count_nodes(root) index = 0 if is_complete(root, index, node_count): print("The tree is a complete binary tree") else: print("The tree is not a complete binary tree") ``` ```java // Checking if a binary tree is a complete binary tree in Java // Node creation class Node { int data; Node left, right; Node(int item) { data = item; left = right = null; } } class BinaryTree { Node root; // Count the number of nodes int countNumNodes(Node root) { if (root == null) return (0); return (1 + countNumNodes(root.left) + countNumNodes(root.right)); } // Check for complete binary tree boolean checkComplete(Node root, int index, int numberNodes) { // Check if the tree is empty if (root == null) return true; if (index >= numberNodes) return false; return (checkComplete(root.left, 2 * index + 1, numberNodes) && checkComplete(root.right, 2 * index + 2, numberNodes)); } public static void main(String args[]) { BinaryTree tree = new BinaryTree(); tree.root = new Node(1); tree.root.left = new Node(2); tree.root.right = new Node(3); tree.root.left.right = new Node(5); tree.root.left.left = new Node(4); tree.root.right.left = new Node(6); int node_count = tree.countNumNodes(tree.root); int index = 0; if (tree.checkComplete(tree.root, index, node_count)) System.out.println("The tree is a complete binary tree"); else System.out.println("The tree is not a complete binary tree"); } } ``` ```c // Checking if a binary tree is a complete binary tree in C #include <stdbool.h> #include <stdio.h> #include <stdlib.h> struct Node { int key; struct Node *left, *right; }; // Node creation struct Node *newNode(char k) { struct Node *node = (struct Node *)malloc(sizeof(struct Node)); node->key = k; node->right = node->left = NULL; return node; } // Count the number of nodes int countNumNodes(struct Node *root) { if (root == NULL) return (0); return (1 + countNumNodes(root->left) + countNumNodes(root->right)); } // Check if the tree is a complete binary tree bool checkComplete(struct Node *root, int index, int numberNodes) { // Check if the tree is complete if (root == NULL) return true; if (index >= numberNodes) return false; return (checkComplete(root->left, 2 * index + 1, numberNodes) && checkComplete(root->right, 2 * index + 2, numberNodes)); } int main() { struct Node *root = NULL; root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); root->right->left = newNode(6); int node_count = countNumNodes(root); int index = 0; if (checkComplete(root, index, node_count)) printf("The tree is a complete binary tree\n"); else printf("The tree is not a complete binary tree\n"); } ``` ```cpp // Checking if a binary tree is a complete binary tree in C++ #include <iostream> using namespace std; struct Node { int key; struct Node *left, *right; }; // Create node struct Node *newNode(char k) { struct Node *node = (struct Node *)malloc(sizeof(struct Node)); node->key = k; node->right = node->left = NULL; return node; } // Count the number of nodes int countNumNodes(struct Node *root) { if (root == NULL) return (0); return (1 + countNumNodes(root->left) + countNumNodes(root->right)); } // Check if the tree is a complete binary tree bool checkComplete(struct Node *root, int index, int numberNodes) { // Check if the tree is empty if (root == NULL) return true; if (index >= numberNodes) return false; return (checkComplete(root->left, 2 * index + 1, numberNodes) && checkComplete(root->right, 2 * index + 2, numberNodes)); } int main() { struct Node *root = NULL; root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); root->right->left = newNode(6); int node_count = countNumNodes(root); int index = 0; if (checkComplete(root, index, node_count)) cout << "The tree is a complete binary tree\n"; else cout << "The tree is not a complete binary tree\n"; } ``` * * * ## 数组索引和树元素之间的关系 完全二叉树具有一个有趣的属性,我们可以用来查找任何节点的子代和父代。 如果数组中任何元素的索引为`i`,则索引`2i+1`中的元素将成为左子元素,而`2i+2`索引中的元素将成为右子元素。 同样,索引为`i`的任何元素的父级都由`(i-1)/2`的下限给出。 让我们测试一下 ``` Left child of 1 (index 0) = element in (2*0+1) index = element in 1 index = 12 Right child of 1 = element in (2*0+2) index = element in 2 index = 9 Similarly, Left child of 12 (index 1) = element in (2*1+1) index = element in 3 index = 5 Right child of 12 = element in (2*1+2) index = element in 4 index = 6 ``` 我们还要确认规则是否适用于寻找任何节点的父节点 ``` Parent of 9 (position 2) = (2-1)/2 = ½ = 0.5 ~ 0 index = 1 Parent of 12 (position 1) = (1-1)/2 = 0 index = 1 ``` 了解数组索引到树位置的这种映射对于了解[堆数据结构](https://www.programiz.com/dsa/heap-data-structure)的工作方式以及如何用于实现[堆排序](https://www.programiz.com/dsa/heap-sort)至关重要。 * * * ## 完全二叉树应用 * 基于堆的数据结构 * [堆排序](https://www.programiz.com/dsa/heap-sort)