[TOC]
性质
二叉搜索树本质上还是一棵二叉树,其满足以下性质(习惯性定义为):
- 非空左子树的所有键值小于其根结点的键值
- 非空右子树的所有键值大于其根结点的键值
- 左右子树都是二叉搜索树
基本函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Poi Find(ElementType x, BinTree BST);
Poi FindMin(BinTree BST);
Poi FindMax(BinTree BST);
BinTree Insert(ElementType x, BinTree BST);
BinTree Delete(ElementType x, BinTree BST);
|
Find
1 2 3 4 5 6 7 8 9 10 11 12 13
| BiNode* BiSearchTree::Find(int x, BiNode* BST){ if (!BST) return nullptr;
if (x < BST->data) { Find(x, BST->left); } else if (x > BST->data) { Find(x, BST->right); } else { return BST; } }
|
FindMin
最小元素一定在树的最左分支的结点
1 2 3 4 5 6
| BiNode* BiSearchTree::FindMin(BiNode* BST){ if (BST) { if (BST->left)return FindMin(BST->left); } return BST; }
|
FindMax
最大元素一定在树的最右分支的结点
1 2 3 4 5 6 7
| BiNode* BiSearchTree::FindMax(BiNode* BST){ if (BST) { if (BST->right)return FindMin(BST->right); } return BST; }
|
Insert
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| BiNode* BiSearchTree::Insert(int x, BiNode* BST){ if (BST) { if (x < BST->data) { BST->left = Insert(x, BST->left); } else if (x > BST->data) { BST->right = Insert(x, BST->right); } else { BST->cnt++; } }else{ BST = new BiNode; BST->data = x; BST->left = BST->right = nullptr; }
return BST; }
|
Delete
需要考虑三种情况
-
要删除的是叶结点:直接删除,再修改其父结点指针NULL
-
要删除的结点只有一个"孩子":将其父结点的指针指向要删除的"孩子"结点
-
要删除的结点有左右两棵子树:用另一结点替代被删除的结点(右子树的最小元素 或 左子树的最大元素)----- 这样做的好处是:右子树的最小值和左子树的最大值一定不会有两个"孩子"的结点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| BiNode* BiSearchTree::Delete(int x, BiNode* BST){ BiNode* tmp = nullptr; if (!BST) { cout << "未找到相应元素" << endl; }else if (x < BST->data) { BST->left = Delete(x, BST->left); } else if (x > BST->data) { BST->right = Delete(x, BST->right); } else{ if (BST->left && BST->right) { tmp = FindMax(BST->left);
BST->data = tmp->data; BST->left = Delete(BST->data, BST->left);
} else { tmp = BST; if (!BST->left) { BST = BST->left; } else if (!BST->right) { BST = BST->right; }
delete tmp; } }
return BST; }
|
平衡二叉树(AVLTree)
- 给定结点数为n的平衡二叉树的最大高度为$log_2n$
插入一个新结点后,如果树的平衡结构被破坏
- 被破坏的是右侧结构:称这次插入为RR插入 应对这种不平衡的调整称为RR旋转(右旋)
↓插入NOV,Mar右侧结构被破坏,需要进行调整
/!/[/]/(/img/page/tree/AVLRR.wepb)