数据结构中的二叉树(示例)
什么是二叉树?
二元这个词的意思是二。在树数据结构中,“二叉树”是指每个节点最多可以有两个子节点(左节点和右节点)的树。它是一棵简单的二叉树。
然而,还有另一种最常用且有多种用例的二叉树。它被称为二叉搜索树 (BST)。这种树可以使搜索算法更快,时间复杂度精确地为 log(n)。在数据结构中,n 表示二叉树中的节点数。
二叉树和二叉搜索树有什么区别?
BST 与常规二叉树的区别在于,BST 左节点的值小于根节点,而右节点的值大于根节点。因此,左子树的值始终小于根节点,而右子树的值始终大于根节点。
二叉搜索树的示例
让我们通过下面的例子来演示二叉搜索树的概念。
在这里,您可以看到所有节点都遵循给定的规则。二叉搜索树中的最大节点数有一个公式。如果我们观察上面的树,我们可以看到除了所有叶节点之外,每个节点都有两个子节点。给定二叉树的高度(h)为 4。公式是 2h - 1。因此,结果为 15。
上图不是完整的二叉树或平衡二叉树,而称为完整二叉树或平衡二叉树。还有另一种数据结构称为 AVL(另一种二叉树),它优化了二叉树的高度并更快地执行 BST 搜索,如图 3 所示。
尝试计算上面给出的二叉树的中序遍历。你会发现它将给出一个非递减的排序数组,并且遍历算法与二叉树相同。
二叉树的类型
以下是一些重要的二叉树类型:
- 完整二叉树: 此二叉树中的每个节点可以有 0 或 2 个子节点。此类型的二叉树不允许只有一个子节点。因此,除叶节点外,所有节点都将有 2 个子节点。
- 完整二叉树: 每个节点可以有 0 或 2 个节点。它看起来像满二叉树,但所有叶元素都倾向于左子树,而在满二叉树中,节点可以位于右子树或左子树中。
- 完美二叉树: 所有节点必须有 0 或 2 个节点,并且所有叶节点应位于同一级别或高度。 上述完整二叉树结构的示例不是完美二叉树,因为节点 6 和节点 1,2,3 不在同一高度。 但完全二叉树的示例是完美二叉树。
- 退化二叉树: 每个节点只能有一个子节点。所有操作(如搜索、插入和删除)都需要 O(N) 时间。
- 平衡二叉树: 在这棵二叉树中,左子树和右子树的高度差最多为 1。因此,在添加或删除节点时,我们需要再次平衡树的高度。这种自平衡二叉树称为 AVL树.
BST 有三种基本操作。下面将详细讨论。
C 语言中二叉树的实现和 C++
#include <iostream> #include <bits/stdc++.h> using namespace std; struct Node { int value; struct Node *left, *right; } struct Node *getEmptynode(int val) { struct Node *tempNode = (struct Node *)malloc(sizeof(struct Node)); tempNode->value = val; tempNode->left = NULL; tempNode->right = NULL; return tempNode; } struct Node *successor(struct Node *node) { struct Node *present = node; // going to the left most node while (present != NULL && present->left != NULL) { present = present->left; } return present; } struct Node *insert(struct Node *node, int value) { if (node == NULL) { return getEmptynode(value); } if (value < node->value) { node->left = insert(node->left, value); } else { node->right = insert(node->right, value); } return node; } int searchInBST(struct Node *node, int value) { struct Node *current = node; while (current->value != value) { if (current->value > value) { current = current->left; } else { current = current->right; } if (current == NULL) { return 0; } } return 1; } void inorder(struct Node *root) { if (root != NULL) { inorder(root->left); cout << root->value << " "; inorder(root->right); } } struct Node *deleteNode(struct Node *node, int value) { if (node == NULL) { return node; } if (value < node->value) { node->left = deleteNode(node->left, value); } else if (value > node->value) { node->right = deleteNode(node->right, value); } else { if (node->left == NULL) { struct Node *temp = node->right; free(node); return temp; } else if (node->right == NULL) { struct Node *temp = node->left; free(node); return temp; } struct Node *temp = successor(node->right); node->value = temp->value; node->right = deleteNode(node->right, temp->value); } return node; } int main() { struct Node *root = NULL; root = insert(root, 8); root = insert(root, 4); root = insert(root, 12); root = insert(root, 2); root = insert(root, 6); root = insert(root, 10); root = insert(root, 14); root = insert(root, 1); root = insert(root, 3); root = insert(root, 5); root = insert(root, 7); root = insert(root, 9); root = insert(root, 11); root = insert(root, 13); root = insert(root, 15); cout << "InOrder Traversal after inserting all nodes: " << endl; inorder(root); root = insert(root, -10); cout << "\nInOrder Traversal after inserting -10 : " << endl; inorder(root); cout << "\nSearching -5 in the BST: " << searchInBST(root, -5) << endl; cout << "Searching -10 in the BST: " << searchInBST(root, -10) << endl; root = deleteNode(root,8); cout<<"After deleting node 8, inorder traversal: "<<endl; inorder(root); root = deleteNode(root,-10); cout<<"\nAfter deleting node -10, inorder traversal: "<<endl; inorder(root); }
输出:
InOrder Traversal after inserting all nodes: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 InOrder Traversal after inserting -10 : 10 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Searching -5 in the BST: 0 Searching -10 in the BST: 1 After deleting node 8, inorder traversal: -10 1 2 3 4 5 6 7 9 10 11 12 13 14 15 After deleting node -10, inorder traversal: 1 2 3 4 5 6 7 9 10 11 12 13 14 15
二叉树的实现 Python
class Node: def __init__(self,value): self.left = None self.right = None self.value = value def insert(root,value): if root == None: return Node(value) if value< root.value: root.left = insert(root.left,value) else: root.right = insert(root.right,value) return root def searchInBST(root,value): current = root while current.value != value: if current.value > value: current = current.left else: current = current.right if current == None: return "Not found" return "Found" def inorder(root): if root != None: inorder(root.left) print(root.value,end=" ") inorder(root.right) def successor(root): present = root while present != None and present.left != None: present = present.left return present def deleteNode(root,value): if root == None: return root if value < root.value: root.left = deleteNode(root.left, value) elif value>root.value: root.right = deleteNode(root.right, value) else: if root.left == None: temp = root.right root = None return temp elif root.right == None: temp = root.left root = None return temp temp = successor(root.right) root.value = temp.value root.right = deleteNode(root.right, temp.value) return root root = Node(8) root = insert(root, 4) root = insert(root, 12) root = insert(root, 2) root = insert(root, 6) root = insert(root, 10) root = insert(root, 14) root = insert(root, 1) root = insert(root, 3) root = insert(root, 5) root = insert(root, 7) root = insert(root, 9) root = insert(root, 11) root = insert(root, 13) root = insert(root, 15) print("InOrder Traversal after inserting all nodes: ") inorder(root) root = insert(root, -10) print("\nInOrder Traversal after inserting -10 : ") inorder(root) print("\nSearching -5 in the BST: ",searchInBST(root, -5)) print("Searching -5 in the BST: ",searchInBST(root, -10)) root = deleteNode(root,8) print("After deleting node 8, inorder traversal:") inorder(root) root = deleteNode(root,-10) print("\nAfter deleting node -10, inorder traversal:") inorder(root)
输出:
InOrder Traversal after inserting all nodes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 InOrder Traversal after inserting -10 : -10 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Searching -5 in the BST: Not found Searching -5 in the BST: Found After deleting node 8, inorder traversal: -10 1 2 3 4 5 6 7 9 10 11 12 13 14 15 After deleting node -10, inorder traversal: 1 2 3 4 5 6 7 9 10 11 12 13 14 15
二叉树的应用
以下是二叉树的一些常见应用:
- 按排序顺序组织节点数据
- 用于编程语言库中的映射和设置节点对象。
- 在数据结构中搜索元素
» 学习我们的下一个教程 组合算法