树(Tree)是数据结构中的一种非常重要的组成部分。它是一种非线性数据结构,用于模拟具有层级关系的数据集合。树结构在计算机科学中有着广泛的应用,例如在组织数据、管理信息层次以及搜索算法等方面。
树的定义:
- 树是由一个根节点(Root)和零个或多个子节点(Children)组成的集合。
- 每个节点都由一个值(Data)和指向其子节点的指针(Children)组成。
- 树的子节点可以进一步拥有自己的子节点,形成层级结构。
树的操作:
- 插入(Insert):向树中添加一个新的节点。
- 删除(Delete):从树中删除一个节点。
- 查找(Search):在树中查找一个节点的值。
-遍历(Traversal):按照一定的顺序访问树中的所有节点。
树的类型:
- 二叉搜索树(Binary Search Tree, BST):是二叉树的一种,具有排序特性。左子节点的值小于根节点的值,右子节点的值大于根节点的值。
#include "BinarySortTree.h"
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
BTreeNode *CreateNode(Elementype element)
{
BTreeNode *newNode = (BTreeNode *)malloc(sizeof(BTreeNode));
if (newNode==NULL)
{
printf("创建新节点失败\n");
return NULL;
}
newNode->data = element;
newNode->left = NULL;
newNode->right = NULL;
newNode->parent = NULL;
return newNode;
}
void InitBSTree(BSTree *tree)
{
tree->root = NULL;
}
void InsertNdoe(BTreeNode*node,Elementype element)
{
if (node==NULL)
{
return;
}
if (node->data>element&&node->left==NULL)
{
node->left = CreateNode(element);
if (node->left==NULL)
{
return;
}
node->left->parent = node;
}
if (node->data<element&&node->right==NULL)
{
node->right = CreateNode(element);
if (node->right==NULL)
{
return;
}
node->right->parent = NULL;
}
if (node->data>element)
{
InsertNdoe(node->left, element);
}
if (node->data<element)
{
InsertNdoe(node->right, element);
}
}
void InsertElement(BSTree *tree, Elementype element)
{
if (tree->root==NULL)
{
tree->root = CreateNode(element);
}
else
{
InsertNdoe(tree->root, element);
}
}
void PrevPrintNode(BTreeNode*node)//前序遍历
{
if (node==NULL)
{
return;
}
printf("%d ", node->data);
PrevPrintNode(node->left);
PrevPrintNode(node->right);
}
void PrevPrint(BSTree *tree)
{
PrevPrintNode(tree->root);
printf("\n");
}
void MidPrintNode(BTreeNode*node)//中序遍历
{
if (node == NULL)
{
return;
}
PrevPrintNode(node->left);
printf("%d ", node->data);
PrevPrintNode(node->right);
}
void MidPrint(BSTree *tree)
{
MidPrintNode(tree->root);
printf("\n");
}
void PostPrintNode(BTreeNode*node)//后序遍历
{
if (node==NULL)
{
return;
}
PrevPrintNode(node->left);
PrevPrintNode(node->right);
printf("%d ", node->data);
}
void PostPrint(BSTree *tree)
{
PostPrintNode(tree->root);
printf("\n");
}
BTreeNode*FindNode(BTreeNode*node,Elementype element)
{
if (node==NULL)
{
return NULL;
}
if (node->data==element)
{
return node;
}
else if(node->data>element)
{
return FindNode(node->left, element);
}
else
{
return FindNode(node->right, element);
}
}
BTreeNode *FindElement(BSTree *tree,Elementype element)
{
return FindNode(tree->root,element);
}
bool IsLeftChild(BTreeNode*node)
{
if (node->parent==NULL)
{
return false;
}
if (node->parent->left==node)
{
return true;
}
else
return false;
}
void RemoveElement(BSTree *tree,Elementype element)
{
BTreeNode *target = FindElement(tree, element);
if (target==NULL)
{
return;
}
if (target->left==NULL&&target->right==NULL)
{
if (target->parent==NULL)//根节点
{
free(target);
tree->root = NULL;
return;
}
if (IsLeftChild(target)==true)
{
target->parent->left = NULL;
}
else
{
target->parent->right = NULL;
}
free(target);
}
else if (target->left!=NULL&&target->right==NULL)
{
target->left->parent = target->parent;
if (target->parent==NULL)
{
tree->root = target->left;
free(target);
return;
}
if (IsLeftChild(target)==true)
{
target->parent->left = target->left;
}
else
{
target->parent->right = target->left;
}
free(target);
}
else if (target->left==NULL&&target->right!=NULL)
{
target->right->parent = target->parent;
if (target->parent == NULL)
{
tree->root = target->right;
free(target);
return;
}
if (IsLeftChild(target) == true)
{
target->parent->left = target->right;
}
else
{
target->parent->right = target->right;
}
free(target);
}
else if (target->left!=NULL&&target->right!=NULL)
{
BTreeNode *MinNode = target->right;//找右子树中最小的节点
while (MinNode->left!=NULL)
{
MinNode = MinNode->left;
}
target->data = MinNode->data;
if (MinNode->parent==target)
{
target->right = MinNode->right;
}
else
{
MinNode->parent->left = MinNode->right;
}
free(MinNode);
}
}
- 平衡树(AVL Tree、红黑树等):是特殊的二叉搜索树,具有自我平衡的特性,保持树的平衡状态,避免查找操作的时间复杂度增加。
树的优点:
- 指针结构使得树的插入和删除操作更加灵活。
- 层级结构使得数据组织更加清晰,便于管理。
- 树的查找、插入和删除操作的时间复杂度相对较低。
树的缺点:
- 需要额外的内存空间来存储节点和指针。
- 遍历操作需要递归或栈结构支持。
总结:
树是一种非常灵活和高效的数据结构,适用于各种具有层级关系的数据组织和管理。了解树的原理和操作方法,能够帮助我们更好地解决实际问题,并在计算机科学领域中发挥重要作用。