数据结构与算法(C++)– 二叉查找树(Binary Search Tree )
1、二叉查找树(BST)
定义: 假设二叉树的节点都是不同的数,对于树点的任一节点,它的左子树都小于它,它的右子树都大于它。
2、二叉查找树的操作
插入: 从根节点开始比较,小于节点则往左比较,大于节点则往右比较。
void Insert(BinaryTree * &tree, int data)
{
if(NULL == tree)
{
tree = new BinaryTree;
tree->data =data;
tree->leftChild = NULL;
tree->rightChild = NULL;
}
else if(tree->data > data)
{
Insert(tree->leftChild, data);
}
else if(tree->data < data)
{
Insert(tree->rightChild, data);
}
}
查找最大最小值: 最左边为最小值,最右边为最大值
// 找最小值, 最左边
int findMin(BinaryTree * tree)
{
if(NULL == tree)
return -1;
else if(tree->leftChild == NULL)
return tree->data;
else
return findMin(tree->leftChild);
}
// 找最大值,最右边
int findMax(BinaryTree * tree)
{
if(NULL == tree)
return -1;
else if(tree->rightChild == NULL)
return tree->data;
else
return findMax(tree->rightChild);
}
删除:删除完节点后,需要从右子树中查找最小值填补。
void Remove(BinaryTree * &tree, int data)
{
if(NULL == tree)
return;
if(data > tree->data)
Remove(tree->rightChild, data);
else if(data < tree->data)
Remove(tree->leftChild, data);
// 如果不符合前两种情况则为=
// 如果左右子树都不为空,则选择右子树最小的值填补当前节点并在右子树删除它
else if(tree->rightChild && tree->leftChild)
{
tree->data = findMin(tree->rightChild);
Remove(tree->rightChild, tree->data);
}
// 如果左右子树至少有一个为空
else
{
BinaryTree *node = tree;
// 左边不为NULL则把指针指向左边,反之
tree = (tree->leftChild) ? tree->leftChild : tree->rightChild;
delete node;
node = NULL;
}
}
3、AVL 树
定义: AVL 树是一种带有平衡条件的特殊二叉搜索树,平衡条件是任一节点的左子树和右子树的高度相差不能超过1。空树的高度是-1。
- AVL树的最大高度大概为1.44log(N + 2) − 1.328,实际只略大于logN。
- 除了插入和删除,AVL数的各种操作的时间复杂度为O(logN) 。
4、平衡AVL树
当按照BST的方式插入新的节点后,可能使AVL树不平衡,需要进一步的操作来平衡。
单旋转:旋转一次、分为左旋转和右旋转
- 右旋转:
- 左旋转
双旋转: 旋转两次、分为左-右旋转和右-左旋转
- 右-左旋转
- 左-右旋转
5、B树
定义:
对于大数据量,为了减少对磁盘的访问,设计了M叉查找树,内存只存指示关键字,把数据存在硬盘。5阶B树如下:
M阶B树的特性:
- M叉树的高度大概为 logM(N)
- L为树叶的数据项个数